关系型数据库,主键用汉字性能会怎样?

2014-07-23 11:03:27 +08:00
 dbfox
[使用汉字word做主键数据表结构]

[keywords] 关键字表
word (PK)
id (自增长标识)

[articles] 文章表
id (PK)(自增长标识)
title

[articleskeywordsrelates] 关键字与文章的关系表

articleid 文章ID(PK) 联合主键
keyword 关键字(PK) 联合主键


获取 文章id 为5 的所有对应的关键字的时候是这样

select keyword from articleskeywordsrelates where articleid=5



[使用数字标识做主键数据表结构]

[keywords] 关键字表
word
id (PK)(自增长标识)

[articles] 文章表
id (PK)(自增长标识)
title

[articleskeywordsrelates] 关键字与文章的关系表

articleid 文章ID(PK) 联合主键
keywordid 关键字ID(PK) 联合主键



获取 文章id 为5 的所有对应的关键字的时候是这样

select word from keywords
where
id in(select keywordid from articleskeywordsrelates where articleid=5)





* keywords 数据量 和 articles 数据量差不多









如果后期扩展 keywords 表,增加一个 pinyin 字段

[keywords] 关键字表
word
id (自增长标识)
pinyin



当需求变更为

获取 文章id 为5 的所有对应的关键字的pinyin 和关键字 的时候


使用汉字主键是:
select * from keywords where word in(select keyword from articleskeywordsrelates where articleid=5)

使用数字主键是:
select * from keywords where id in(select keywordid from articleskeywordsrelates where articleid=5)




唉,还是很麻烦啊

多表关联很麻烦,谁有好的设计??
4508 次点击
所在节点    问与答
6 条回复
incompatible
2014-07-23 11:17:52 +08:00
你的表设计本身就没什么问题(除了用word作为keywords表的主键这一部分。 我看不出来有什么理由要这样做)
多表关联在设计业务系统时是很普遍的用法,你不应该怕麻烦

另外:
这种写法性能差select * from keywords where id in(select keywordid from articleskeywordsrelates where articleid=5)

建议改成
select kw.*
from keywords kw
join articlekeywordsrelates akr on kw.id=akr.keywordid
where akr.articleid=5



关于你标题的问题
http://dba.stackexchange.com/questions/232/character-vs-integer-primary-keys
sampeng
2014-07-23 14:41:10 +08:00
汉字的根本是二进制。
字符串对比。性能100%不会比int型对比快。你放弃吧
dbfox
2014-07-23 21:33:07 +08:00
@sampeng
@incompatible

好吧,感谢 回复

同时我想到了比较好的办法,

既简单又高效 (自己实验过性能,同时认为有一定的便捷性)

这个其实我很早就在用,今天特意实验了下性能,测试了下 比 in 性能高出几十倍

结构如下:

[keywords]
id
name

[articles]
id
title
keywords

数据示例如下:

[keywords]

id name

1 苹果
2 安卓
3 游戏
4 wp
5 编程
6 CSS
7 JS
8 Javascript


[articles]

id title keywords

1 xxx /苹果/游戏/编程/js/
2 xxx /安卓/wp/编程/js/
3 xxx /游戏/CSS/编程/js/
4 xxx /CSS/wp/编程/js/
5 xxx /Javascript/wp/编程/js/





查出 id为5 的所有关键字


[SQLServer] mysql locate 代替 charindex

select * from keywords where CharIndex('/'+Name+'/',(select keywords from articles where id=5))>0

简单点就是如下:

select * from keywords where CharIndex('/'+Name+'/','/Javascript/wp/编程/js/')>0





如果不想破坏关系的话,可以保留 articleskeywords 关系表
sampeng
2014-07-24 16:33:47 +08:00
原来是这个需求。。。。关系表绰绰有余。多对多即可。。
可维护性和代码的可理解程度都比这个强百倍。性能?多对多建好索引。不会比你这个一条一条查慢。。你这种查询,索引是一点都用不到的。直接全表查找。小数据ok。大数据。。你explain就知道了。
sampeng
2014-07-24 16:35:25 +08:00
如果没数据量的要求就无所谓了。
有一点很重要啦~性能和可维护性。要平衡。。如果快出的性能是无所谓的。。选择可维护性。
sampeng
2014-07-24 17:09:57 +08:00
用in肯定慢。。你用left join啊。。
in和left join的解析和实现过程完全不是一回事。只有没有办法的办法

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/124044

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX