17611538698
webmaster@21cto.com

面向开发者的数据库设计技巧

数据库 0 40 16小时前
图片
导读:数据库设计是个精细工作,你需要先熟悉第三范式,还有一些本文要讲述的一些规约。

凡是软件中有Bug之类的东西最终都会腐烂,这已经是一个普遍真理。

事情会慢慢起变化。一开始看起来很酷很干净的东西,不知不觉就变成了“他们到底在想什么?”

但这并不意味着我们可以袖手旁观,任由其发展。我们应该像一只刚意识到自己被主人穿了袜子的猫一样,尽力去对抗“代码腐败”。 

代码腐败的一个领域是数据库设计,但这个领域没有得到人们足够的重视。

在这里,我将重点介绍一些你可能不太关注的、不太重要的数据库设计技巧。我们称之为“小而重要的规则”。

每个表都有一个 ID 字段

这可能有些争议,但我始终认为数据库里的每个表都应该有一个名为ID 的主键ID。就是这样,只是叫ID。注意,不是CustomerID,不是OrderID,只是ID。 

它应该是一个自动递增的整数值(或者,如果你有非常充分的理由UUID,比如分布式系统,也可以使用自动递增的整数值)。当然,该字段应该有一个索引ID。 

对于不是多对多关系交叉引用的表,你需要多字段键的情况应该非常非常罕见。

切勿在表名或字段名中添加空格

在此,我向那些认为在表名或字段名中添加空格(或使用汉字)是个好主意的人致以永远的鄙视。

你千万别这么干,名称中的空格会让你使用引号,而你很容易忘记,这会让你在编写查询时不禁自问:“到底带空格还是不带空格?” 这真是太麻烦了。永远不要使用空格,这样你就再也不用为此烦恼了。

还有,为了可爱的猫王宝宝,请不要在名字中使用下划线。我真不知道人们怎么能忍受打出“像这样的名字”。光是想,我的小手指就想去申请工伤赔偿。

表名是复数

再次强调,这是一个很大的争论,但我认为表格代表很多东西,而不是单一的东西。因此,表格名称应该始终使用复数形式。例如,应该使用 Customers,而不是 Customer。这样,当你看到“customers”这个词时Orders,你就知道它指的是表格。如果你将表格命名为Order“order”,就会在“order”这个词周围产生歧义。你指的是表格本身还是表格中的一行?

我知道这个问题已经讨论过很多了。我强烈倾向于使用复数名称。无论你做什么,选择一个系统并坚持下去。

外键应清晰标记

还记得我上面提到的字段ID吗?现在它就派上用场了。

如果表中有一行Orders引用了客户(即外键),请将其命名为 name CustomerID。任何命名的字段ID都将始终是该表的外键。在整个架构中始终如一地执行此操作,这样就能始终清楚地了解哪些字段是外键,以及这些字段引用的是哪个表。

索引查询的内容

为出现在WHERE、JOIN或ORDER BY子句中的每个字段添加索引。坚持这样做可以避免很多性能问题。可能会有例外,但你应该通过索引(而不是索引不足)来发现它们。假设需要索引,然后让查询分析器说服你删除任何导致问题的索引。 

参照完整性不是可选的

确保表之间的关系保持完整,并且数据库中没有孤立记录,对于数据完整性至关重要。所有现代关系数据库都具有引用完整性。从一开始就严格遵循并执行它。不要依赖代码来维护这些关系。数据库本身就具备这种能力,我们应该充分利用它。

不要在代码中嵌入 SQL

如果你曾经在代码中嵌入 SQL,哪怕“就这一次”,你也终生都会后悔。更别提它为“再来一次”打开了方便之门。

嵌入 SQL 会使你的代码变得杂乱无章,并与数据库耦合,最终导致代码混乱不堪。请记住,让数据库来做这些事吧。 

如果你非得需要在代码中使用 SQL,请将其与代码分开维护,并且不需要编译器处理它。将其存储在单独的文件中,这些文件可以嵌入或在代码外部使用,并且可以在不更改代码逻辑的情况下进行更新。

还有一些额外想法

一般来说,如果数据库能帮你做,你就让它帮你做。数据库处理数据的能力比你强 453.7 倍,不要试图替代它们。 

如果想添加以 1、2、3 等结尾的字段,请不要这样做。阅读有关规范化的内容。

为列使用正确的数据类型。不要将布尔值设为数字,也不要将日期设为字符串。

强烈建议在每个表中添加CreatedAt时间戳UpdatedAt字段。你会惊讶地发现,你最终会庆幸自己这么做。使用触发器自动生成这些时间戳,它们会变得实用且轻松。

还有参数化存储过程也是我们的好朋友,要尽可能多地使用它们。

查询分析器在决定查询数据的最佳方式方面比你高出一个数量级。

此外,请谨慎使用布尔值。Null 会将布尔值转换为量子态——在执行查询之前,既不是真也不是假。除非你确切了解 null 在特定上下文中的含义,否则请勿使用布尔值。

不要依赖字符串值来定义状态。请使用枚举值,确保数据永远不会出错。比如不要status = 'bananna',因为有人误操作了某个字段而导致出错。

结语

我在这里给各位列了很多该做和不该做的事情。

再次强调,最重要的一点是制定一套规则,并严格执行。今天就这么做,以后就能省去很多麻烦。

相信我,未来的你会感谢现在的自己!

作者:行动中的大雄

评论