MYSQL三部曲(二)的准备数据

复制代码
DROP TABLE IF EXISTS `class`;
CREATE TABLE `class` (
  `cid` int(11) NOT NULL AUTO_INCREMENT,
  `caption` varchar(32) NOT NULL,
  PRIMARY KEY (`cid`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
# innodb 有外键约束 myisam 注释的作用
DROP TABLE IF EXISTS `course`; CREATE TABLE `course` (   `cid` int(11) NOT NULL AUTO_INCREMENT,   `cname` varchar(32) NOT NULL,   `teacher_id` int(11) NOT NULL,   PRIMARY KEY (`cid`),   KEY `fk_course_teacher` (`teacher_id`),   CONSTRAINT `fk_course_teacher` FOREIGN KEY (`teacher_id`) REFERENCES
`teacher` (`tid`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `score`; CREATE TABLE `score` (   `sid` int(11) NOT NULL AUTO_INCREMENT,   `student_id` int(11) NOT NULL,   `course_id` int(11) NOT NULL,   `num` int(11) NOT NULL,   PRIMARY KEY (`sid`),   KEY `fk_score_student` (`student_id`),   KEY `fk_score_course` (`course_id`),   CONSTRAINT `fk_score_course` FOREIGN KEY (`course_id`) REFERENCES `course` (`cid`),   CONSTRAINT `fk_score_student` FOREIGN KEY (`student_id`) REFERENCES `student` (`sid`) ) ENGINE=InnoDB AUTO_INCREMENT=53 DEFAULT CHARSET=utf8;

DROP TABLE IF EXISTS `student`; CREATE TABLE `student` (   `sid` int(11) NOT NULL AUTO_INCREMENT,   `gender` char(1) NOT NULL,   `class_id` int(11) NOT NULL,   `sname` varchar(32) NOT NULL,   PRIMARY KEY (`sid`),   KEY `fk_class` (`class_id`),   CONSTRAINT `fk_class` FOREIGN KEY (`class_id`) REFERENCES `class` (`cid`) ) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8;

DROP TABLE IF EXISTS `teacher`; CREATE TABLE `teacher` (   `tid` int(11) NOT NULL AUTO_INCREMENT,   `tname` varchar(32) NOT NULL,   PRIMARY KEY (`tid`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
复制代码

【】为什么innodb 建议主动创建主键索引,并且以自增的整数作为主键 ?

  1. InnoDB引擎表是基于B+树的索引组织表
  2. 如果我们定义了主键(PRIMARY KEY),那么InnoDB会选择主键作为聚集索引、如果没有显式定义主键,则InnoDB会选择第一个不包含有NULL值的唯一索引作为主键索引、如果也没有这样的唯一索引,则InnoDB会选择内置6字节长的ROWID作为隐含的聚集索引(ROWID随着行记录的写入而主键递增,这个ROWID不像ORACLE的ROWID那样可引用,是隐含的)。
  3. 数据记录本身被存于主索引(一颗B+Tree)的叶子节点上。这就要求同一个叶子节点内(大小为一个内存页或磁盘页)的各条数据记录按主键顺序存放,因此每当有一条新的记录插入时,MySQL会根据其主键将其插入适当的节点和位置,如果页面达到装载因子(InnoDB默认为15/16),则开辟一个新的页(节点)
  4. 如果表使用自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页
  5. 如果使用非自增主键(如果身份证号或学号等),由于每次插入主键的值近似于随机,因此每次新纪录都要被插到现有索引页得中间某个位置,此时MySQL不得不为了将新记录插到合适位置而移动数据,甚至目标页面可能已经被回写到磁盘上而从缓存中清掉,此时又要从磁盘上读回来,这增加了很多开销,同时频繁的移动、分页操作造成了大量的碎片,得到了不够紧凑的索引结构,后续不得不通过OPTIMIZE TABLE来重建表并优化填充页面。
  6. 综上总结,如果InnoDB表的数据写入顺序能和B+树索引的叶子节点顺序一致的话,这时候存取效率是最高的

【】CONSTRAINT,约束语句

【】FOREIGN KEY是外键,外键只能引用外表中的列的值。有外键的表是子表,被其他表引用主键的表是父表(外键必须是外表的主键)。删除父表被外键约束的行,子表中对应的行也会被删掉。InnoDB外键的定义写法:

  • [CONSTRAINT `约束名` ] FOREIGN KEY (`外键字段`) REFERENCES `父表`(`主键字段`) 

【】KEY,设置索引

【】CHARSET设置字符编码

【】列名不要用关键字,如果用关键字,要加反引号屏蔽关键字检测 ` `

posted @   幻cat  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示