前言:
数据库设计是一种艺术,好的设计不仅能够使业务逻辑更加清晰,还可以对性能和效率带来提高。
我们来说一下数据库的设计目标:
Eliminate Data Redundancy: the same piece of data shall not be stored in more than one place. This is because duplicate data not only waste storage spaces but also easily lead to inconsistencies.
Ensure Data Integrity and Accuracy. (--from wiki)
简单的来说就时消除代码的冗余,避免重复的数据出现,保证数据的安全和准确。
一般数据库表关系分为三种:
- One to Many
- Many to Many
- One to One
下面逐一讲解一下:
One to Many
生活中有很多一对多的关系,比如一个老师可以有多个学生,一个商场里可以有很多店铺,一个公司可以有很多的分公司。
比如建一个公司的表,他可以有很多的分公司,我们先用这种方式建表,一张表:company
company_id company_name address tel sun_company ...
01 alibaba china 021-22154 taobao ...
01 alibaba china 021-22154 tianmao ...
01 alibaba china 021-22154 zifubao ...
...
有没有发现什么不足的地方,对于这张表中公司id,name,address都是不变的重复数据,为了关联子公司的信息,我需要每条数据都
带入总公司的信息。严重的冗余。而且这样的表,带来的是操作执行效率的低下。比如,我要修改company_name,那么我要修改那么多重复的条数。
那我们怎么做呢,分表:另建一个子公司表,把总公司id关联进去:
table: company
company_id company_name address tel ...
01 alibaba china 021-22154 ...
table: sun_company
company_id sun_company_id sun_company ...
01 211 taobao ...
01 212 tianmao ...
01 213 zifubao ...
这样一来避免了company表由于对应多个sun_company而造成的本身元素重复的问题。这就是One to Many的设计方式。我们要的是One -> Many。 而不是One + Many
Many to Many
多对多的关系,比如一个author(作者)可以写了很多的书,而一本book可以有很多的作者,这就是多对多的关系。
其实,多对多的关系就是两个一对多的关系的叠加。
我先来说一个作者有很多书:
table: author
author_id author_name address tel ...
01 jack Us 021-22154 ...
02 jim Us 021-22154 ...
table: author_book
autor_id book_id book_name price ...
01 897 python 90.0 ...
01 898 java 60.0 ...
02 898 java 60.0 ...
参照我们的One to Many的方式,我们做出的作者和书本的一对多的关系。但是有没有发现一个问题,对于book_id=898的书本,它对应多个作者,
这导致插入多条数据,导致书本信息重复。出现了One to Many中我们演示的第一种的“错误示例”的做法。
现在怎么办?是不是要把book另建一张表,设计成book -> author的One to Many模式。这里就不展示了。然后将author -> book 的一对多和 book -> author的一对多组合。
最终的Many to Many 设计:
table: author
author_id author_name address tel ...
01 jack Us 021-22154 ...
02 jim Us 021-22154 ...
table: book
book_id book_name price ...
897 python 90.0 ...
898 java 60.0 ...
table: author-book
author_id book_id
01 897
01 898
02 898
这三张表的设计,使得author和book的信息表相互独立,他们的关联采用一张关联表进行关联。减少了表之间的粘黏性,和数据重复带来的效率性能问题。
One to One
一对一的关系相对简单。比如我有一个订单(Order)储存订单的一些基本信息,然后又一个订单详情(Order_detail)描述订单的详细信息。一个订单只有一个订单详情,一个订单
详情只对应唯一的订单。
问题:为什么不做成一张表,这种一对一的关系不会产生数据重复啊?
是的,一张表并不会带来数据重复的问题。但会带来效率和性能的问题。比如,我在订单页面需要显示所有的订单,而只要显示每条订单的基本信息,当我需要看到某一个订单
的详细信息的时候,才回去获取这条订单的详细的信息。那好,如果是一张表我需要去这么庞大的数据里去抽出所需的数据,带来的性能和效率下降是必然的。所以,当实际项目
中遇到像订单这样,又需要基本信息和详细信息的,我们可以采用这种方式来提高我们的数据库性能和效率。
由于一对一比较容易理解,就不举例了。
上面就是对数据库表设计的一些基本的理解。重要的不是怎么实现,而是为什么要什么做。因为在实际的项目中可能遇到各种不一样的情况和业务逻辑。我们要根据需求去做出最
有效,最佳的表结构设计。所以一切的出发点是: What's the best way to do it ?