Sql多值属性的处理

在日常生活中会遇到一种场景——多值属性,比如电话号码,手机、工作的、家庭的、小灵通、IP电话…一个人可能拥有其中一种或者每一种。如果将这些值存储在一列中,势必要用到分隔符,这会导致sql操作的复杂、也无法确保数据的正确性。如果用多列存储,不优雅。因为每次查询一个人的电话时,需要扫描每一列;每当增加或者删除一种通讯工具时,需要重构整张表;数据库中可能存在更多的null列。不过,当我们在设计数据库时,所以如果想采用多列存储某种类似的属性,首先要保证分开的这些列是可区分的,且列的数目是固定的。

但是还有更好的办法是创建另一张新表,将多列属性转化为多行存储。(这个例子可能不是最恰当的)

1
2
3
4
5
6
7
create table communication (	
employee_id int,
tag varchar(20),
content varchar(20),
primary key (employee_id, tag),
foreign key (employee_id) references employee (id)
)

利用标签将不同的值分在多行存储起来,多列——>多行;同时又有外键关联,将人和信息联系在一起;同时查询、更新、删除都变得简单;支持或取消对某种通讯工具的支持(增加或删除某种通讯工具),也同样不需要重构数据库,只需要来个遍历,删除相应的行即可。

PS:当然了,这里所提到的多列属性是违反第一范式的设计。在一张表中,多个列拥有了相同的值域,这不能满足关系数据库的基础。关系中的每一行(每一条记录)都是从不同数据域上选择一个值而形成的组合。