请教表结构设计问题:一对多。
本帖最后由 misscai 于 2011-01-07 09:25 编辑
最近做一个项目,设计一个表结构,用于记录个人的兴趣爱好,目前的表结构设计如下。
create table Person --人员表
(ID int, --唯一索引
Name varchar(20), --姓名
Hobby_ID varchar(50)) --兴趣爱好ID
create table Hobby --爱好
(ID int, --唯一索引
Hobby_Name varchar(10)) --兴趣爱好表述
表的数据如下:
ID Name Hobby_ID
---- -------------------- -----------------
1 张三 1,2,3
2 李四 1,3
3 王五 2
ID Hobby_Name
--------------- -----------
1 游泳
2 健身
3 旅游
我遇到的问题是erson.Hobby_ID用字符串记录兴趣爱好的枚举ID,在程序中处理时每次都要对字符串进行拆分后,再与Hobby表进行关联,十分影响性能。
我试想过用中间表记录兴趣爱好,后来察觉中间表可能会非常大。
我的中间表设计如下:
Person_ID Hobby_ID
-------------- ------------
1 1
1 2
1 3
2 1
2 3
3 2
因为在业务环境中,Person表数据集是千万级的,Hobby表数据集也是不确定的。
所以,各位大虾在设计这种表结构时是如何做的?
最近做一个项目,设计一个表结构,用于记录个人的兴趣爱好,目前的表结构设计如下。
create table Person --人员表
(ID int, --唯一索引
Name varchar(20), --姓名
Hobby_ID varchar(50)) --兴趣爱好ID
create table Hobby --爱好
(ID int, --唯一索引
Hobby_Name varchar(10)) --兴趣爱好表述
表的数据如下:
ID Name Hobby_ID
---- -------------------- -----------------
1 张三 1,2,3
2 李四 1,3
3 王五 2
ID Hobby_Name
--------------- -----------
1 游泳
2 健身
3 旅游
我遇到的问题是erson.Hobby_ID用字符串记录兴趣爱好的枚举ID,在程序中处理时每次都要对字符串进行拆分后,再与Hobby表进行关联,十分影响性能。
我试想过用中间表记录兴趣爱好,后来察觉中间表可能会非常大。
我的中间表设计如下:
Person_ID Hobby_ID
-------------- ------------
1 1
1 2
1 3
2 1
2 3
3 2
因为在业务环境中,Person表数据集是千万级的,Hobby表数据集也是不确定的。
所以,各位大虾在设计这种表结构时是如何做的?
作者: misscai 发布时间: 2011-01-07
建议:爱好不要用like , like是个关键字。 看着不爽。 用hobby也行啊。
人员表的兴趣爱好ID建议改成integer类型,爱好表需要3列(或以上)
create table hobby (
hobby_id int not null, ---爱好ID
seq int not null, ---爱好的序号
hobbies varchar(255) null ---爱好内容
)
楼主需要看看关系型数据库的理论。
人员表的兴趣爱好ID建议改成integer类型,爱好表需要3列(或以上)
create table hobby (
hobby_id int not null, ---爱好ID
seq int not null, ---爱好的序号
hobbies varchar(255) null ---爱好内容
)
楼主需要看看关系型数据库的理论。
作者: andkylee 发布时间: 2011-01-07
你的人员表中爱好列存储1,2,3这样的数据。 甚至可以说都不满足关系型数据库的第一范式的要求了。
作者: andkylee 发布时间: 2011-01-07
QUOTE:
建议:爱好不要用like , like是个关键字。 看着不爽。 用hobby也行啊。
人员表的兴趣爱好ID建议改成 ...
andkylee 发表于 2011-01-07 09:21
人员表的兴趣爱好ID建议改成 ...
andkylee 发表于 2011-01-07 09:21
谢谢你的建议,已改。
若按照你的方案,Person.Hobby_ID改为Integer字段,那多个兴趣如何记录?
请赐教!
作者: misscai 发布时间: 2011-01-07
seq int not null, ---每个人的爱好的序号
作者: andkylee 发布时间: 2011-01-07
其实ankylee就是直接用你的那个联立表来做数据表就最合适了。上面建上合理的索引和分区应该就不错了。
换言之——以空间换效率。
换言之——以空间换效率。
作者: Eisen 发布时间: 2011-01-07
你的这个例子和数据库管理系统中的一个表有多列相似嘛。
兴趣爱好中存储,1,2,3这样的数据, 感觉你像是在开发程序, 而不是在设计表结构。
create table persion --爱好
(ID int, --唯一索引
name varchar(20),
hobby_id int --兴趣爱好表述
create table hobby (
hobby_id int not null, ---爱好ID
seq int not null, ---爱好的序号
hobbies varchar(255) null ---爱好内容
)
查询某人的所有兴趣爱好,用如下的SQL:
select p.name,h.seq,h.hobbies from person p,hobby h
where p.hobby_id = h.hobby_id
and p.name='张三'
这样的设计难道不是很简单吗?
兴趣爱好中存储,1,2,3这样的数据, 感觉你像是在开发程序, 而不是在设计表结构。
create table persion --爱好
(ID int, --唯一索引
name varchar(20),
hobby_id int --兴趣爱好表述
create table hobby (
hobby_id int not null, ---爱好ID
seq int not null, ---爱好的序号
hobbies varchar(255) null ---爱好内容
)
查询某人的所有兴趣爱好,用如下的SQL:
select p.name,h.seq,h.hobbies from person p,hobby h
where p.hobby_id = h.hobby_id
and p.name='张三'
这样的设计难道不是很简单吗?
作者: andkylee 发布时间: 2011-01-07
回复 Eisen
像这种场景,我觉得不能用数据分析的那套理论来用空间换时间。原因:如果人员表还有其他的如性别、年龄、籍贯、电话等信息的话,数据冗余度很高;数据可能需要经常更新(人的兴趣在变嘛,呵呵~);查询的话可能会查询某人的所有兴趣,或者有某个特定兴趣的人员信息。
建索引、表分区都是提高性能的方法。
像这种场景,我觉得不能用数据分析的那套理论来用空间换时间。原因:如果人员表还有其他的如性别、年龄、籍贯、电话等信息的话,数据冗余度很高;数据可能需要经常更新(人的兴趣在变嘛,呵呵~);查询的话可能会查询某人的所有兴趣,或者有某个特定兴趣的人员信息。
建索引、表分区都是提高性能的方法。
作者: andkylee 发布时间: 2011-01-07