首页 > MySQL > 浅谈MySQL主键
2009七月10

浅谈MySQL主键

主键没有着明确的概念定义,其是索引的一种,并且是唯一性索引的一种,且必须定义为“PRIMARY KEY”,是只可意会不可言传的东西。下面让我用通俗,甚至有些低俗的语言为您简单介绍一下MySQL的主键。

简单描述:

主键不能重复,就像QQ的用户名,有N个叫“虫zi”的网友,可是他们的QQ号码是不一样的,也就是说真正标识一个QQ的身份是“QQ号码”。还有那万恶的身份证,无论“张三,李四,王二麻子”这些都不能代表一个人,真正能代表一个人确切身份的就是那个“天朝特色的万恶的身份证”,相当于在杀猪的时候给猪盖个章,说这头是检验过的,有身份的猪,只不过人是生下来用“证”给你确定了,虽然要18岁才给你颁发。

不过主键和QQ号不一样,因为一个表只能有一个主键,而一个人可以有多个QQ号,这也是为什么人们喜欢在虚拟世界里面互相忽悠,因为你真的不知道电脑那面坐的是一头猪。

貌似扯的有点远了,接着来看我们的MySQL主键。

声明主键的方法:

  • 您可以在创建表的时候就为表加上主键,如:
    CREATE TABLE tbl_name ([字段描述省略...], PRIMARY KEY(index_col_name));
  • 也可以更新表结构时为表加上主键,如:
    ALTER TABLE tbl_name ADD PRIMARY KEY (index_col_name,…);

主键示例:

主键被认为是NOT NULL和UNIQUE约束最好的结合。如果这些列没有被明确地定义为NOT NULL,MySQL会隐含地定义这些列。

/*
创建一个qq表,将qq_id设为主键,且没有对其进行NOT NULl约束
*/

create table qq(
qq_id int(10),
nick_name varchar(255) not null,
primary key (qq_id)
)
/*
插入一条数据,将qq号设为10000(咱也幻想一下),昵称设为"simaopig"
*/

INSERT INTO qq( qq_id, nick_name )
VALUES (
'10000', 'simaopig'
);
/*
插入一条数据,qq号仍为10000,因为数据库内已经存在其10000这样的数据,
而且最最主要的是其QQ号为主键,所以报错,信息如下
#1062 - Duplicate entry '10000' for key 'PRIMARY'
*/

INSERT INTO qq( qq_id, nick_name )
VALUES (
'10000', 'chongpig'
)
/*
虽然没有将qq号字段设NOT NULL约束,可是因为其是主键,所以其不能为NULL
#1048 - Column 'qq_id' cannot be null
*/

INSERT INTO qq( qq_id, nick_name )
VALUES (
NULL , 'chongpig'
)

主键也是索引:

刚才已经说了,主键其实也是索引,甚至在MySQL的术语里面“键”就等于“索引”,所以“外键”一定要先设为“索引”,这个咱们下篇日志再来讨论。所以主键也应该和索引一样,既可以作用于单独的字段,又可以作用于多个字段

举个简的例子吧,我住3单元,501室,我叫小小子,那么只有3单元501室才能在本小区表里面唯一确定我家。因为2单元,501室住着的可能也是个小小子,所以只有两个字段才能唯一确定我,也就是说可以二者组合作为主键。组合的主键,每个列都会隐含定义NOT NULL约束,且其二者加在一起被定义了UNIQUE 惟一约束。

例子不写自己想的了,书中举的例子更是恰当,那就是一个防火墙,由host和port组合确定一个防火墙。代码示例如下:

/*
创建防火墙表,将host 和port组合设为主键,注意我没有将port设NOT NULL约束
*/

create table firewall(
host varchar(11) not null,

port smallint(4),

access enum('deny', 'allow') not null,

primary key (host,port)
)
/*
插入一条新的记录,没有啥问题
1 row(s) inserted.
*/

INSERT INTO firewall (
host ,
port ,
access
)
VALUES (
'202.65.3.87', '21', 'deny'
);
/*
插入失败,因为host 加port的主键值202.65.3.87-21已经存在了
#1062 - Duplicate entry '202.65.3.87-21' for key 'PRIMARY'
*/

INSERT INTO firewall (
host ,
port ,
access
)
VALUES (
'202.65.3.87', '21', 'allow'
);
/*
没声明NOT NULl port也不能为NULL
#1048 - Column 'port' cannot be null
*/

INSERT INTO firewall( host, port, access )
VALUES (
'192.168.0.1', NULL , 'deny'
)

在这个示例中,host和port都可以重复,但是不能同时重复,因为其是组合主键。且二者都不能被插入NULL,因为其是主键。

我们可以看一下phpmyadmin,看一下port字段的默认值为0,这和昨天我们讲的索引规则是一样的,NOT NULL并且给设了DEFAULT,因其是整型所以为0,如果其为字符串的话,默认值就是”

文章作者:simaopig
本文地址:http://www.xiaoxiaozi.com/2009/07/10/1140/
版权所有 © 转载时必须以链接形式注明作者和原始出处!

15 Responses to “浅谈MySQL主键”

  1. #1 小明猪 回复 | 引用 Post:2009-07-11 01:33

    呵呵,这些基本知识,所以草草看一下,四毛猪不要怪我啦,刚刚10点多才有空,更新了自己那边,又找了些东西,都回访到两点了都,我想睡觉了 :D

    [回复]

  2. #2 simaopig 回复 | 引用 Post:2009-07-11 08:49

    @小明猪
    呵,怎么能怪你呢。我昨天在家调试页面来着。
    我们新上线一个页面,可是却有一个BUG,帮产品经理弄来着,弄到了十点半,
    十一点我才写的日志。呵呵。

    [回复]

  3. #3 huaimao 回复 | 引用 Post:2009-07-11 19:26

    呵呵,偶以后有PHP和MYSQL的问题,可以在找帅锅你了哈!嘿嘿……

    [回复]

  4. #4 bolo 回复 | 引用 Post:2009-07-11 19:34

    囧,看到firewall就不开心了

    [回复]

  5. #5 jomor 回复 | 引用 Post:2009-07-11 20:00

    我对这方面了解不深学习了

    [回复]

  6. #6 micogle 回复 | 引用 Post:2009-07-11 21:53

    :roll: 一直在学习中……

    [回复]

  7. #7 simaopig 回复 | 引用 Post:2009-07-11 22:32

    @huaimao
    呵,好的。没问题。咱们互相学习 :D

    @bolo
    呃,我真该换个例子。呵呵。

    @micogle
    我也一直在学习。嗯。

    [回复]

  8. #8 simaopig 回复 | 引用 Post:2009-07-11 22:33

    @jomor
    我也是现学现卖,呵呵。

    [回复]

  9. #9 newcoin 回复 | 引用 Post:2009-07-12 01:01

    去我空间帮我留个言,送个祝福,谢谢了

    [回复]

  10. #10 simaopig 回复 | 引用 Post:2009-07-12 09:05

    @newcoin
    幸福的一对,已经去过了。呵。

    [回复]

  11. #11 JetKing 回复 | 引用 Post:2009-07-14 12:51

    很久没来了,发现你又开始做MYSQL普及了哈。。
    最近段时间都没怎么看博,貌似我也得学习下你的勤奋~ :roll:

    [回复]

  12. #12 simaopig 回复 | 引用 Post:2009-07-14 12:52

    @JetKing
    呵呵,是给自己留个备忘而已。
    你应该是很忙吧最近?嗯。呵呵,正事要紧。

    [回复]

  13. #13 JetKing 回复 | 引用 Post:2009-07-14 14:42

    @simaopig
    都是瞎忙些鸡毛蒜皮的小事。。

    [回复]

  14. #14 simaopig 回复 | 引用 Post:2009-07-14 16:08

    @JetKing
    呵呵,我一到周末就杂事特别多。呵呵。

    [回复]

显示 隐藏 1 trackbacks

发表评论

:wink: :twisted: :roll: :oops: :mrgreen: :lol: :idea: :evil: :cry: :arrow: :?: :-| :-x :-o :-P :-D :-? :) :( :!: 8-O 8)