首页 存档 技术 查看内容

数据库设计的 7 个常见错误

2018-3-30 13:00 |来自: 互联网 353 0

摘要: (点击上方公众号,可快速关注) 理论说得够多了!通过实例来学习数据库建模 为何要讨论错误? 优秀数据库设计的艺术就像游泳。入手相对容易,精通则很困难。如果你想学习设计数据库,一定得有一些理论背景,比如关 ...

(点击上方公众号,可快速关注)


理论说得够多了!通过实例来学习数据库建模


为何要讨论错误?


优秀数据库设计的艺术就像游泳。入手相对容易,精通则很困难。如果你想学习设计数据库,一定得有一些理论背景,比如关于数据库设计范式和事务隔离级别的知识。但你还应该尽可能地多加练习,因为可悲的事实就是,我们在犯错中学习得更多。


本文中,通过展示在设计数据库时常犯的一些错误,我们尝试把学习数据库设计变得容易一点。


注意,我们假定读者了解数据库范式并知道一点关系数据库的基础知识,因而不会去讨论数据库规范化。只要有可能,文中所涵盖的主题都将使用 Vertabelo 建模和实例来说明。


本文涵盖了设计数据库的各个方面,但着重于Web应用,因此有些例子可能是特定于web应用程序的。


模型设计


假设我们想要为一个在线书城设计数据库。该系统应当允许用户执行以下活动:


  • 通过书名、描述和作者信息浏览与搜索书籍,


  • 阅读后对书籍添加评论和评级,


  • 定购书籍,


  • 查看订单处理的状态。


那么最开始的数据库模型可能如下所示:




为了测试该模型,我们使用Vertabelo为其生成SQL,并且在PostgreSQL RDBMS中创建一个新的数据库。


该数据库有8张表,其中没有数据。我们已经往里面填充了一些人工生成的测试数据。现在数据库里包含了一些示范数据,准备好开始模型检查了,包括识别那些现在不可见但将来在真实用户使用时会出现的潜在问题。


1 使用无效的名称


你可以在上面的模型中看到我们用“order”命名了一张表。不过,或许你还记得,“order”在SQL中是保留字! 因此如果你试图发起一个SQL查询:


SELECT * FROM ORDER ORDER BY ID


数据库管理系统将会**。很幸运,在PostgreSQL中用双引号把表名包裹起来就行了,语句仍可以执行:


SELECT * FROM "order" ORDER BY ID


等等,可是这里的“order”是小写!


没错,这值得深究。如果你在SQL中用双引号把什么包了起来,它就变成分隔标识符,大多数数据库将以区分大小写的方式解释它。由于“order” 是SQL中的保留字,Vertabelo生成SQL会自动把order用双引号包起来:


CREATE TABLE "order" (

id int NOT NULL,

customer_id int NOT NULL,

order_status_id int NOT NULL,

CONSTRAINT order_pk PRIMARY KEY (id)

);


但是由于标识符被双引号包裹且是小写,表名仍然是小写。现在如果你希望事情变得更复杂,我可以创建另一个表,这次把它名为ORDER(大写),PostgreSQL不会检测到命名冲突:


CREATE TABLE "ORDER" (

id int NOT NULL,

customer_id int NOT NULL,

order_status_id int NOT NULL,

CONSTRAINT order_pk2 PRIMARY KEY (id)

);


如果一个标识符没有被双引号包裹,它就被称作“普通标识符”,在被使用前自动被转成大写这是SQL 92标准所要求的。但是标识符如果被双引号包裹


就被称作“分隔标识符”要求被保持原样。


底线就是不要使用关键字来当做对象名称。永远不要。


你知道Oracle中名称长度上限是30个字符吗?


关于给表以及数据库其他元素命好名这里命好名的意思不仅是“不与SQL关键字冲突”,还包括是自解释的且容易记住这一点常常被严重低估。在一个小型数据库中,比如我们这个,命名其实并不是件非常重要的事。但是当你的数据库增长到100、200或者500张表,你就会知道在项目的生命周期中为保证模型的可维护性,一致和直观的命名至关重要。


记住你不光是给表和列命名,还包括索引、约束和外键。你应当建立命名约定来给这些数据库对象命名。记住名字的长度也是有**的。如果你给索引命名太长,数据库也会**。


提示:


  • 让你的数据库中的名字:

    • 尽可能短,

    • 直观,尽可能正确和具有描述性,

    • 保持一致性;


  • 避免使用SQL和数据库引擎特定的关键字作为名字;


  • 建立命名约定;


以下是把order表重命名为purchase后的模型:



模型中的改变如下:



2 列的宽度不足


让我们进一步来看这个模型。如我们所看到的,在book_comment表中,comment列的类型是1000个以内的字符。这意味着什么?


假设这个字段将是GUI(用户只能输入非格式化的评论)中的纯文本,那么它简单地意味着该字段可以存储最多1000个文本字符。如果是这样的话这里没有错误。


但是如果这个字段允许一些格式化的动作,比如bbcode或者HTML,那么用户实际上输入进去的字符数量是未知的。假如他们输入一个简单的评论,如下:


I like that book!


那么它会只占用17个字符。然而如果他们使用粗体格式化它,像这样:

I

声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

相关分类