我开始使用MySQL开发应用程序,尽管我在使用数据库之前已经开发了应用程序,但我通常会使用递增id方法。有一天,我正在某个地方阅读一个帖子,看到有人因为没有正确地“正常化数据库”而被分开。我不是一个大数据库人,但我想确保我做对了。
任何想法,帮助/指导?
答案 0 :(得分:5)
选择primary key有两种主要方法:
这两种方法都有一般优点和缺点,您可能希望在某些情况下选择自然键,在其他情况下选择代理键。
我希望这只是一个简短的介绍,以便您可以进一步研究如何选择合适的主键。
答案 1 :(得分:2)
COMPOSITE PK方法
drop table if exists users;
create table users(
user_id int unsigned not null auto_increment primary key, -- clustered auto_inc PK
username varbinary(32) not null,
unique key users_username_idx(username)
)engine=innodb;
insert into users (username) values ('f00'),('bar'),('bish'),('bash'),('bosh'),('F00');
drop table if exists user_friends;
create table user_friends(
user_id int unsigned not null,
friend_user_id int unsigned not null,
primary key (user_id, friend_user_id) -- clustered composite PK
)engine=innodb;
insert into user_friends values
(1,2),(1,3), (2,1),(2,5), (3,5), (4,1),(4,2),(4,3),(4,5),(4,6), (5,4),(5,1);
大部分时间我都在查询想要列出给定用户的所有朋友的user_friends 所以我的查询正在利用聚集主键(user_id,friend_user_id)
select * from user_friends where user_id = 4; -- uses PK index
如果我想删除朋友,我有一个复合PK,所以我需要指定user_id和 我要删除的friend_user_id - 需要满足密钥的两个部分。这个 习惯让你的应用程序逻辑变得更复杂。
delete from user_friends where user_id = 4 and user_friend_id = 5; -- uses PK index
AUTO INC PK APPROACH (用户表保持不变)
drop table if exists user_friends;
create table user_friends(
friend_id int unsigned not null auto_increment primary key, -- clustered auto_inc PK
user_id int unsigned not null,
friend_user_id int unsigned not null,
unique key user_friends_idx (user_id, friend_user_id) -- non clustered secondary index
)engine=innodb;
大部分时间我都在查询想要列出给定用户的所有朋友的user_friends 在这种情况下,我无法利用主键,我需要创建一个辅助 index on(user_id,friend_user_id)。现在我在这个表上有2个索引PK索引 强制实体完整性和辅助索引,有助于优化我的查询。
添加二级索引会产生相关的成本。插入/删除现在必须 更新2个索引与仅一个复合键索引,它占用更多的磁盘空间。
select * from user_friends where user_id = 4; -- uses secondary index not PK
然而,如果我想删除一个朋友,我可以使用friend_id PK,这简化了我的 应用程序逻辑,因为我可以使用PK轻松删除1行。
delete from user_friends where friend_id = 10; -- uses PK index
这可能不是这两种方法的一个很好的例子,但它应该给你一些想法,为什么有时使用聚簇复合索引:)
答案 2 :(得分:1)
增加id与规范化无关。规范化与删除传递和减少依赖关系有关。无论您选择使用自动递增ID还是其他形式的主键,都是完全不同的事情。
答案 3 :(得分:0)
自动增量ID和规范化无关(即,您可以在非规范化数据库中使用自动增量ID,或者使用不使用自动增量ID的规范化数据库)。