本文转载请联系Java极客技术公众号。你在开发的时候,很多时候不是有人告诉你,数据库已经完全设计好了,没有专门的人来管理数据库表设计的内容,而是阿芬的朋友好伤心,接手了一个公司。同事的一个比较重要的功能,阿芬的朋友没有重新设计,所以才出现了这个场景。你设计了什么?领队:你们数据库设计中的软删除呢?直接给我删?如果用户反悔了,想查询某条数据怎么办?我:.......(内心OS:这不是我设计的好吗?)领导:快加给我,我告诉你需求。看他之前做了多少,把没做过的功能都填上。.我:……好吧(内心OS:对不起,他做这么久的功能,就这么点小事,你让我快点完成,你是傻子吗?)领导:看这个,两个表的相关字段不是同一个类型。如果您不使用相同的名称,请不要使用它。你们的类型不一样,怎么行,你们赶紧统一吧。我:……(这明显不是我设计的手表好吗?这种低智商的行为我能做得到吗?)但是当阿芬的朋友向阿芬抱怨的时候,说明心态有问题了受到影响。这显然不是我的错。最后,我将承担所有的过错。但是想想看。毕竟,如果这个功能很容易做到,为什么我的同事会辞职?接下来说一下这个数据库表的设计。怎样设计才能更好?数据库表设计遵循数据库表设计范式(1)的原则。第一个范式(确保每一列保持原子性)是什么意思?什么?百度一搜,结果是所有的字段值都是不可分解的原子值。就这点来说,有点难以理解。在这种情况下,我们不得不考虑现实生活中是否存在这样的案例。比如我们保存一些地址信息的时候,一般都是Use,province,city,然后加上具体的位置来表示完整的地址。很少有人会直接在数据库中设计一个地址字段。比如我们设计产品的时候,都是产品、数量、价格,而不是设计成商品1,商品2,商品3,数量1,数量2,数量3。数据库的第一范式是1NF。事实上,它不仅保证了每一列的原子性,而且如果两列的属性相似或相近或相同,则尽量合并具有相同属性的列,以确保不会产生冗余数据。阿芬上面提到的产品就是这种情况。(2).第二范式在数据库表中,一张表中只能存储一种类型的数据,不能在同一个数据库表中存储多种类型的数据。每行数据只能与其中一个列相关,即一行数据只能做一件事。只要数据列中存在数据重复,就必须对表进行拆分。上面这句话好像有点多余。同样的数据信息在普通人的设计中是不会出现在同一张表中的,因为毕竟有些字段如果一直重复的话,数据量就更不用说了。也会出现左不好,左不好,写SQL会出现各种问题。(3).第三范式中的数据不能有传递关系,即每个属性都与主键有直接关系,不能有间接关系。阿芬之前接过一个项目,就是A指向B,B指向C,补充说我们现在有一个订单,订单里面必须有人员信息,我们会有一个人员信息表的Id对应订单中的人员信息。此时尽量不要在订单中存储该人员的其他相关信息,如姓名、身份证号等信息。这时候我们在获取订单信息的时候,可以直接通过当前用户的ID查询到所有对应的订单,所有的人员信息都包含在人员信息表中。说到这里,阿芬其实想说,数据库的三种范式只是一个原则,并不是必须遵循的原则,因为有时候,在创建表的时候,是根据我们的需要制定的。范式也有优缺点:在设计数??据表时,范式的优点很明显,避免数据冗余,减少维护数据完整性的麻烦,减少数据库空间,数据变化快,但缺点也很明显。按照范式标准设计的表,范式设计的层次越高,设计的表就越多。获取数据时,关联表过多,性能较差。阿芬看过很久以前的一个项目,一个医疗系统,设计了2000多块手表,阿芬当时就震惊了。据说是很久以前一个程序员设计的。当时严格按照范式设计数据库,结果可想而知。一个SQL查询,关联那么多表,效率能有多少?学会根据要求定制。还记得之前阿芬写的使用UUID生成主键,被diss了吗?比如前面的比较,数据库自增,雪花算法生成ID,UUID生成ID,这三者的比较,结果是100w条数据,最后的赢家是雪花算法。如果您对此感兴趣,可以阅读这篇文章。使用uuid作为数据库的主键,被技术总监惊呆了!为什么说要学会通过需求来定制,因为首先要明确,你写的和最终实际落脚点都是需求,这个需求已经实现了。在不出意外的情况下,需求永远是第一位的。如果非要把一个简单的一对多关系拆分成多对多关系,这完全是多余的。而这种通过需求来定制,其实可以称之为反范式。反范式设计也有明显的优点和缺点。几乎所有业务场景需要的数据都可以在一张表上展现,数据冗余。但它缩短了业务响应时间。之所以现在有一些中间件存在,是因为随着公司业务的扩大,数据量越来越大。有时一张表的数据超过百万,甚至上千万。当你写一个WhenNOTIN的时候,你会发现一秒,两秒,三秒……时间就这样过去了。阿里开发手册其实之前阿粉也研究过一段时间的阿里开发手册,比如:【强制】:在表达一个概念的时候,必须以is_xxx的形式命名,数据类型使用unsignedtinyint(1,表示是,0表示否)比如你在数据库表中设计软删除的概念,你选择使用is_delete或者选择使用deleted。其实60%以上的人都会用到is_delete,这个delete的设计,一般很多都是刚入行的年轻人,没有领域设计的概念。【强制】:表名不使用复数名词。比如我们的activityActivity,如果你把它设计成Activities,当你创建一个实体类的时候,Activity和Activities是不是感觉不一样?第二个看起来总是有点不舒服。有兴趣的可以在公众号回复阿里,获取阿里开发手册泰山版。关于数据库设计,你还想知道什么?
