数据库设计
1 需求
- 表结构
- 字段类型、是否允许为null、是否有默认值
- 索引设计
- 数据库引擎的选择
2 注意事项
-
为了查询效率,可以做冗余字段设计(空间换时间的思想,属于一种反范式设计)
-
字段类型的选择
-
整型的存储大小与显示大小
mysql的字段,unsigned int(3), 和unsinged int(6), 能存储的数值范围是否相同。如果不同,分别是多大?
我们建立下面这张表:
CREATE TABLE `test` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `i1` int(3) unsigned zerofill DEFAULT NULL, `i2` int(6) unsigned zerofill DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8
-
发现,无论是int(3), int(6), 都可以显示6位以上的整数。但是,当数字不足3位或6位时,前面会用0补齐。
手册解释是这样的:
> MySQL还支持选择在该类型关键字后面的括号内指定整数值的显示宽度(例如,INT(4))。该可选显示宽度规定用于显示宽度小于指定的列宽度的值时从左侧填满宽度。显示宽度并不限制可以在列内保存的值的范围,也不限制超过列的指定宽度的值的显示。
也就是说,int的长度并不影响数据的存储精度,长度只和显示有关,为了让大家看的更清楚,我们在上面例子的建表语句中,使用了zerofill。
最终答案:**存储范围相同**。
-
char 与 varchar 的选择
- char 不可变,查询效率高,可能造成存储浪费
- varchar 可变,查询效率不如char,节省空间
常见MySQL数据类型
类 型 | 大 小 | 描 述 |
---|---|---|
CAHR(Length) | Length字节 | 定长字段,长度为0~255个字符 |
VARCHAR(Length) | String长度+1字节或String长度+2字节 | 变长字段,长度为0~65 535个字符 |
TINYTEXT | String长度+1字节 | 字符串,最大长度为255个字符 |
TEXT | String长度+2字节 | 字符串,最大长度为65 535个字符 |
MEDIUMINT | String长度+3字节 | 字符串,最大长度为16 777 215个字符 |
LONGTEXT | String长度+4字节 | 字符串,最大长度为4 294 967 295个字符 |
TINYINT(Length) | 1字节 | 范围:-128127,或者0255(无符号) |
SMALLINT(Length) | 2字节 | 范围:-32 768~32 767,或者0~65 535(无符号) |
MEDIUMINT(Length) | 3字节 | 范围:-8 388 608~8 388 607,或者0~16 777 215(无符号) |
INT(Length) | 4字节 | 范围:-2 147 483 648~2 147 483 647,或者0~4 294 967 295(无符号) |
BIGINT(Length) | 8字节 | 范围:-9 223 372 036 854 775 808~9 223 372 036 854 775 807,或者0~18 446 744 073 709 551 615(无符号) |
FLOAT(Length, Decimals) | 4字节 | 具有浮动小数点的较小的数 |
DOUBLE(Length, Decimals) | 8字节 | 具有浮动小数点的较大的数 |
DECIMAL(Length, Decimals) | Length+1字节或Length+2字节 | 存储为字符串的DOUBLE,允许固定的小数点 |
DATE | 3字节 | 采用YYYY-MM-DD格式 |
DATETIME | 8字节 | 采用YYYY-MM-DD HH:MM:SS格式 |
TIMESTAMP | 4字节 | 采用YYYYMMDDHHMMSS格式;可接受的范围终止于2037年 |
TIME | 3字节 | 采用HH:MM:SS格式 |
ENUM | 1或2字节 | Enumeration(枚举)的简写,这意味着每一列都可以具有多个可能的值之一 |
SET | 1、2、3、4或8字节 | 与ENUM一样,只不过每一列都可以具有多个可能的值 |
-
索引
-
主键 Primary Key
-
外键 Foreign Key
- 保持数据完整性
ALTER TABLE tbl_name ADD [CONSTRAINT [symbol]] FOREIGN KEY [index_name] (index_col_name, ...) REFERENCES tbl_name (index_col_name,...) [ON DELETE reference_option] [ON UPDATE reference_option]
例如:
ALTER TABLE `user_resource` CONSTRAINT `FKEEAF1E02D82D57F9` FOREIGN KEY (`user_Id`) REFERENCES `sys_user` (`Id`)
CASCADE
在父表上update/delete记录时,同步update/delete掉子表的匹配记录
- ON DELETE:删除主表时自动删除从表。删除从表,主表不变
- ON UPDATE:更新主表时自动更新从表。更新从表,主表不变
SET NULL
在父表上update/delete记录时,将子表上匹配记录的列设为null (要注意子表的外键列不能为not null)
- ON DELETE:删除主表时自动更新从表值为NULL。删除从表,主表不变
- ON UPDATE:更新主表时自动更新从表值为NULL。更新从表,主表不变
NO ACTION
如果子表中有匹配的记录,则不允许对父表对应候选键进行update/delete操作
- ON DELETE:从表记录不存在时,主表才可以删除。删除从表,主表不变
- ON UPDATE:从表记录不存在时,主表才可以更新。更新从表,主表不变
RESTRICT
同no action, 都是立即检查外键约束
SET DEFAULT
父表有变更时,子表将外键列设置成一个默认的值 但Innodb目前不支持
-
索引 Key / Index
- 提升查询效率,减慢增删改速度
-
唯一约束 Unique
- 保证数据不重复
- MySQL数据库引擎
详情请见上一篇几种MySQL数据库引擎优缺点对比
-