Python(数据库之约束表的关系)
一、约束 约束条件与数据类型的宽度一样,都是可选参数 作用:用于保证数据的完整性和一致性 主要分为: RIMARY KEY (PK) 标识该字段为该表的主键,可以唯一的标识记录 FOREIGN KEY (FK) 标识该字段为该表的外键 NOT NULL 标识该字段不能为空 UNIQUE KEY (UK) 标识该字段的值是唯一的 AUTO_INCREMENT 标识该字段的值自动增长(整数类型,而且为主键) DEFAULT 为该字段设置默认值 UNSIGNED 无符号 ZEROFILL 使用0填充 说明: 1.是否允许为空,默认NULL,可设置NOT NULL,字段不允许为空,必须赋值 2. 字段是否有默认值,缺省的默认值是NULL,如果插入记录时不给字段赋值,此字段使用默认值 sex enum('male','female') not null default 'male' age int unsigned NOT NULL default 20 必须为正值(无符号) 不允许为空 默认是20 3. 是否是key 主键 primary key 外键 foreign key 索引 (index,unique...) 二、not null + default # 默认null (可传空) create table t15( id int, name char(16) not null, sex enum('male','female','other') not null default "male" # 常用用法: not null 和 default连用 ); insert into t15(id,name) values #另一种传值方法 (1,'egon1'), (2,'egon2'), (3,'egon3'); 三、unique: 限制字段的值唯一(约束); 加速查询 1、单列唯一 create table t16( id int unique, #key: PRI name char(16) ); 2、联合唯一 create table server( id int unique, ip char(15), port int, unique(ip,port) #ip可以重复,port可以重复,ip+port不可重复 ); 四、primary key: primary key就等同于not null unique(约束);加速查询;innodb 用主键(一种索引)字段为依据组织数据,形成一种树型结构,从而加速查询 1、强调(******) a、一张表中必须有,并且只能有一个主键 #如果没有主动指定primary key,从上至下把找到的第一个not null unique变成primary key #如果没有主动指定primary key,且没有not null unique,默认一个隐藏字段(7bytes)为主键,并根据其组织数据结构;进而丧失了加速查询优势 b、一张表中都应该有一个id字段,而且应该把id字段做成主键
create table t17( id int primary key, #key:PRI name char(16), age int, sex char(6) )engine=innodb; 2、联合主键 (联合主键可看作一个主键) create table t19( ip char(15), port int, primary key(ip,port) ); 3、primary key auto_increment a、通常与primary key连用,而且通常是给id字段加 b、auto_incremnt只能给被定义成key(unique key,primary key)的字段加 create table t20( id int primary key auto_increment, name char(16) )engine=innodb; 4、总结 key(索引)为mysql中一种特殊的数据结构 a、unique 约束条件,加速查询 b、primary key 约束条件,加速查询,innodb组织数据结构的依据 c、index key 加速查询 d、foreign key 没有加速查询功能 表之间的关系 一、表与表之间的关系 a、一对多 b、多对多 c、一对一 二、如何判断表与表之间的关系(多对一,多对多,一对一): a、左表与右表之间是否有多对一的关系 (多个员工属于一个部门) b、右表与左表之间是否有多对一的关系 (多个部门拥有一个员工) i、a True & b False 多对一 ii、a False & b True 多对一 iii、a True & b True 多对多 iv、a False & b False 一对一 三、所有数据都存放于一张表中的弊端: 1、表的组织结构复杂不清晰 2、浪费空间 3、扩展性极差 解决方案:分表 a、分表 + foreign key: 有硬性限制(关联表中的关联字段内容必须来自于被关联表),但后续修改删除麻烦(不能直接修改,删除要先删除关联对象中的相应元素再删除被关联对象中的相应元素) #foreign key (MUL): 可以理解成外部有一个硬性限制 b、分表 + foreign key + on update cascade on delete cascade: 有硬性限制,对被关联表进行修改删除,关联表相应元素跟着改变;强耦合 c、分表: 靠逻辑上的关系维护,解开耦合 四、表与表之间的关系之多对一(两张表之间单向的多对一关系,称为多对一) i、a True & b False 多对一 ii、a False & b True 多对一 实现多对一: 在emp表中新增一个dep_id字段,该字段指向dep表的id字段 foreign key会带来什么样的效果? 约束1:在创建表时,先建被关联的表dep,才能建关联表emp create table dep( id int primary key auto_increment, dep_name char(10), dep_comment char(60) ); create table emp( id int primary key auto_increment, name char(16), gender enum('male','female') not null default 'male', dep_id int, foreign key(dep_id) references dep(id) ); 约束2:在插入记录时,必须先插被关联的表dep,才能插关联表emp insert into dep(dep_name,dep_comment) values ('sb教学部','sb辅导学生学习,教授python课程'), ('外交部','老男孩上海校区驻张江形象大使'), ('nb技术部','nb技术能力有限部门'); insert into emp(name,gender,dep_id) values ('alex','male',1), ('egon','male',2), ('lxx','male',1), ('wxx','male',1), ('wenzhou','female',3); 约束3:更新与删除都需要考虑到关联与被关联的关系 a、单单只加foreign key:有硬性限制,但后续修改删除麻烦(不能直接修改,删除要先删除关联对象中的相应元素再删除被关联对象中的相应元素) b、foreign key + on update cascade on delete cascade: 1)先删除关联表emp,再删除被关联表dep,准备重建 mysql> drop table emp; mysql> drop table dep; 2)重建:新增功能,同步更新,同步删除 create table dep( id int primary key auto_increment, dep_name char(10), dep_comment char(60) ); create table emp( id int primary key auto_increment, name char(16), gender enum('male','female') not null default 'male', dep_id int, foreign key(dep_id) references dep(id) on update cascade on delete cascade #一条语句 ); insert into dep(dep_name,dep_comment) values ('sb教学部','sb辅导学生学习,教授python课程'), ('外交部','老男孩上海校区驻张江形象大使'), ('nb技术部','nb技术能力有限部门'); insert into emp(name,gender,dep_id) values ('alex','male',1), ('egon','male',2), ('lxx','male',1), ('wxx','male',1), ('wenzhou','female',3); 3)效果演示之同步删除 mysql> select * from dep; +----+------------------+------------------------------------------------------------------------------------------+ | id | dep_name | dep_comment | +----+------------------+------------------------------------------------------------------------------------------+ | 1 | sb教学部 | sb辅导学生学习,教授python课程 | | 2 | 外交部 | 老男孩上海校区驻张江形象大使 | | 3 | nb技术部 | nb技术能力有限部门 | +----+------------------+------------------------------------------------------------------------------------------+ 3 rows in set (0.00 sec) mysql> select * from emp; +----+------------------+--------+--------+ | id | name | gender | dep_id | +----+------------------+--------+--------+ | 1 | alex | male | 1 | | 2 | egon | male | 2 | | 3 | lxx | male | 1 | | 4 | wxx | male | 1 | | 5 | wenzhou | female | 3 | +----+------------------+--------+--------+ 5 rows in set (0.00 sec) mysql> delete from dep where id=1; Query OK, 1 row affected (0.02 sec) mysql> select * from dep; +----+------------------+------------------------------------------------------------------------------------------+ | id | dep_name | dep_comment | +----+------------------+------------------------------------------------------------------------------------------+ | 2 | 外交部 | 老男孩上海校区驻张江形象大使 | | 3 | nb技术部 | nb技术能力有限部门 | +----+------------------+------------------------------------------------------------------------------------------+ 2 rows in set (0.00 sec) mysql> select * from emp; +----+------------------+--------+--------+ | id | name | gender | dep_id | +----+------------------+--------+--------+ | 2 | egon | male | 2 | | 5 | wenzhou | female | 3 | +----+------------------+--------+--------+ 2 rows in set (0.00 sec) 3)效果演示之同步更新 mysql> select * from emp; +----+------------------+--------+--------+ | id | name | gender | dep_id | +----+------------------+--------+--------+ | 2 | egon | male | 2 | | 5 | wenzhou | female | 3 | +----+------------------+--------+--------+ 2 rows in set (0.00 sec) mysql> update dep set id=200 where id =2; Query OK, 1 row affected (0.04 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from dep; +-----+------------------+------------------------------------------------------------------------------------------+ | id | dep_name | dep_comment | +-----+------------------+------------------------------------------------------------------------------------------+ | 3 | nb技术部 | nb技术能力有限部门 | | 200 | 外交部 | 老男孩上海校区驻张江形象大使 | +-----+------------------+------------------------------------------------------------------------------------------+ 2 rows in set (0.00 sec) mysql> select * from emp; +----+------------------+--------+--------+ | id | name | gender | dep_id | +----+------------------+--------+--------+ | 2 | egon | male | 200 | | 5 | wenzhou | female | 3 | +----+------------------+--------+--------+ 2 rows in set (0.00 sec) 五、清空表 1、delete from tb1; 上面的这条命令确实可以将表里的所有记录都删掉,但不会将id重置为0 该条命令不是用来清空表的,delete是用来删除表中某一些符合条件的记录 (delete from tb1 where id > 10;) 2、truncate tb1; 如果要清空表,使用truncate tb1; 作用:将整张表重置 六、多对多(两张表之间是一个双向的多对一关系,称之为多对多) iii、a True & b True 多对多 实现多对多:建立第三张表,该表中有一个字段fk左表的id,还有一个字段是fk右表的id create table author( id int primary key auto_increment, name char(16) ); create table book( id int primary key auto_increment, bname char(16), price int ); insert into author(name) values ('egon'), ('alex'), ('wxx') ; insert into book(bname,price) values ('python从入门到入土',200), ('葵花宝典切割到精通',800), ('九阴真经',500), ('九阳神功',100) ; create table author2book( id int primary key auto_increment, author_id int, book_id int, foreign key(author_id) references author(id) on update cascade on delete cascade, foreign key(book_id) references book(id) on update cascade on delete cascade ); insert into author2book(author_id,book_id) values (1,3), (1,4), (2,2), (2,4), (3,1), (3,2), (3,3), (3,4);