Ⅰ、主键( Primary Key )& 自增( Auto-Increment )
一. 简单描述一下什么是主键 ?
1. 当创建一个表时,可以将某个字段设置为主键( Primary Key ),即:唯一标识
举个栗子:
1. 学生表 ( 学号,姓名,性别,院校,专业 ) ,可想而知,一个学校的每一个学生的学号都是唯一的,学号就是一个主键
2. 课程表 ( 课程代码,课程名称,课程性质,学分 ) ,而课程代码是唯一的,即课程代码就是一个主键
1. 本文档建议读者在所有的表中使用主键,但并非必须
2. 在使用时,我们一般会将主键同时设置成自增【特殊情况除外】
2. 主键起到了一个唯一标识的作用,保证我们可以安全的更改或删除表中指定的某一行( 没主键,这个操作就很麻烦 )
3. MySQL 会把主键单独拿出来,存为一个索引,进行某种规则的排序后存储起来,方便后续的查找
小提示:
1. 我们一般首选整数型 (int) 列的数据作为主键,字符型( varchar )次之
2. 举个栗子:在学校中查找一个人,查找学号肯定是最准确、最方便,也最快速的方式
3. int 是固定的 4 个字节,char 在 1 ~ 255 字节之间,首选 int,占用空间小,节省 CPU 开销
4. 在使用中,通常会在主键上建立索引,使用整形可以将更多的索引载入内存,从而提高性能
5. 使用 int 才可以使用 AUTO_INCREAMENT( 自增 ),见第 四 点
6. int 虽好,却也会导致锁竞争等问题,但总的来说利大于弊,感兴趣的读者可以自行研究
二、主键的设计遵循那些原则 ?
1. 唯一的标识一行( 即不允许重复 )
2. 作为一个可以被外键有效引用的对象。
3. 一个表中最多只有一个主键,联合主键见第四点
4. 主键无关序列,可以是一张表中的任何一个序列,但不能是 NULL 值( 一般由 整形 或 字符串 的列表示主键 )
如图所示,我们将 identityCard ( 身份证号 ) 设置成了 varchar 类型【注意要指定长度】,并将其设为了主键 注意:
1. 本文档不建议使用这么糟糕的主键
2. 这次我们没有使用自增
三、联合主键也能叫主键 ?
举个栗子,按照如下表进行采购手机,要怎么买才不会出错呢 ?
品牌商 | 系统 | 版本 | 采购配置 | 价格 |
小番茄 | Android 8 | Note 7 | 4G + 64GB | 999 |
小灵通 | Android 8 | Note 6 | 6G + 64GB | 999 |
小风车 | Android 8 | Note 8 | 4G + 64GB | 999 |
小番茄 | Android 8 | Note 8 | 6G + 32GB | 1199 |
小蜜蜂 | Android 8 | Note 6 | 6G + 32GB | 1099 |
- 品牌商 ,不能作为主键,因为制作商旗下有很多不同版本的手机
- 版本 ,不能作为主键,因为同一型号下,不同的品牌商有不同的版本
- 但是, " 品牌商 " ," 版本 " ," 采购配置 " ,三者联合在一起,就可以唯一标识一个指定的手机 。
注意,联合主键仍然是一个主键,这里是由三个字段联合在一起组成的。
如图所示:
学校可以通过学号,电话,QQ,微信四种常见方式联系到该学生
四、自增为啥要和主键一起讲?
1. 自增( Auto-Increment )
1. 当整形字段为主键时,一般会同时将其设置为自增( 特殊情况不用设置 )
2. 意思是插入数据时,由 MySQL 来生成 ID,保证 ID 是自增的( 每次加1 )
2. 自增的起点
1. 新建的表,默认从 1 开始
2. 若表中有数据,从上一个最大值开始
3. 过号作废,不会重复
4. 可以指定起点
5. 同样的,此设置也有一些更加深入的问题,建议各位初学者晋级找工作阶段再深入研究
如图所示,身份证号或者学号都是可以作为主键的,但是这里不建议使用自增选项
小提示:非空选项表示在数据录入时,不能输入空值
Ⅱ、数据类型
向表添加一列( 字段 )时,需要指定列的数据类型,各位读者可以参考 MySQL 官方的详细教程,传送门:https://dev.mysql.com/doc/refman/5.7/en/data-types.html
1. MySQL 的数据类型大致可以分为 5 类:
小提示:
1. 如果读者不确定,或者图省事,直接用典型的类型即可
2. 以后可以尝试更多类型
3. 如果你想把一个图片文件作为一列存储到数据里...( 通常这是一个坏主意! )
分类 | 典型 | 更多 |
整数 | int( 4 字节) | tinyint,smallint,int,bigint,... |
字符串 | varchar( 可变长度字符串【10 KB 以下】,使用时指定最大长度,如:5,19,21,... ) | char( 固定长宽字符串 32 ),varchar,... |
浮点数 | double( 8 字节 ) | double,float( 4 字节 ), ... |
日期时间 | datetime ( 日期时间,如:2018-6-7 14:07:54) | date( 日期 ),time( 时间 ),datetime,timestamp,... |
大块数据 | text / blob( 二进制大对象 ) | tinytext,text( 65 KB ),mediumtext( 16 MB ),longtext( 4 GB ),blob( 存储大段字节数据 ),... |
Ⅲ、列的属性:列名( Column Name )
一. 列名的命名规范 ?
1. 本文档不建议使用中文,通常使用英文或拼音,但可以在注释一列中添加中文提示
2. 推荐的命名规范:
-
-
-
-
-
- 不要使用 SQL 里的关键词,如:database,table,...
- 使用有意义的单词或者简写,如:realName,storePath,...
- 第一个单词小写( 与 Java 兼容,减少麻烦 )
-
-
-
-
二. 列的属性:
1. 长度( Length )
-
-
-
-
-
- 对于 varchar / text 字段,需要设置最大长度
- 不区分中英文,按字符数统计
- 太长的字符串,不适合用varchar存储 (65K),varchar(512) 和 varchar(1024) 实质没有差别
- 对于其他类型,不需要设置长度 (意义不大),例如,:int(4) 表示最小显示宽度为 4,不足时凑空格 或 0,( 需勾选 ZeroFill 属性 )
-
-
-
-
2. 非空( Not NULL )
- 空值 NULL:指这一列的值尚未设置
- 当一列设置为 " 非空 " 时,表示该列不允许空值
辨析:其实和 Java 里的含义相同:
String str = null; // 空值NULL String str = ""; // 空字符串
3. 默认值 ( Default Value):指的是当添加一行时,若某列的值未设置,则自动填一个默认值。