https://blog.csdn.net/u012750578/article/details/15026677

Mysql表的约束设计和关联关系设计

======================表的完整性======================

(1)实体完整性:每条记录有一个唯一标识符,通常用无任何业务含义的字段表示(主键)

(2)参照完整性:一张表的某个字段必须引用另一张表的某个字段值(外键)

(3)域完整性:域即单元数据,域中的数值必须符合一定的规则

定义主键约束

primary key:不允许为空,不允许重复

删除主键:alter table tablename drop primary key ;

定义主键自动增长(id,没有业务含义)

auto_increment(MySQL特有/UUID类生成)

定义唯一约束

unique

定义非空约束

not null

定义外键约束

constraint ordersid_FKforeign key(ordersid) references orders(id),

2 键的概念

(1)主键:只有唯一字段

(2)组合主键:由多个字段组合起来,形成唯一字段

(3)外键:针对多张表之间的关联

3 主键的特点

(1)主键不能重复

(2)主键不能为NULL

(3)auto_increment是MySQL特有的,默认从1开始,该ID值与表同生亡

(4)多人项目中,通常使用UUID来生成唯一的主键值,便于多个合并数据时依然保持实体完整性

--id主键

mysql> create table teacher(id intprimary key,

-> name varchar(20),

-> brithday date);

Query OK, 0 rows affected (0.61 sec)

mysql> select * from teacher;

Empty set (0.00 sec)

mysql> insert into teachervalues(1,'jack','1992-2-12');

Query OK, 1 row affected (0.11 sec)

mysql> select * from teacher;

+----+------+------------+

| id | name | brithday   |

+----+------+------------+

|  1| jack | 1992-02-12 |

+----+------+------------+

1 row in set (0.00 sec)

mysql> desc teacher;

+----------+-------------+------+-----+---------+-------+

| Field   | Type        | Null | Key |Default | Extra |

+----------+-------------+------+-----+---------+-------+

| id      | int(11)     | NO   | PRI | NULL    |      |

| name    | varchar(20) | YES  |     | NULL   |       |

| brithday | date        | YES |     | NULL    |      |

+----------+-------------+------+-----+---------+-------+

3 rows in set (0.00 sec)

--主键不能重复,主键冲突,1代表第一列,即id列

mysql> insert into teachervalues(1,'marry','1996-2-12');

ERROR 1062 (23000): Duplicate entry '1' forkey 'PRIMARY'

mysql>

--主键不能为null

mysql> insert into teachervalues(null,'marry','1996-2-12');

ERROR 1048 (23000): Column 'id' cannot benull

-- 删除主键,主键在表只有一个,要么是一列,要么是多列

mysql> alter table teacher drop primarykey;

Query OK, 1 row affected (2.13 sec)

Records: 1 Duplicates: 0  Warnings: 0

mysql> desc teacher;

+----------+-------------+------+-----+---------+-------+

| Field   | Type        | Null | Key |Default | Extra |

+----------+-------------+------+-----+---------+-------+

| id      | int(11)     | NO   |    | NULL    |       |

| name    | varchar(20) | YES  |     | NULL   |       |

| brithday | date        | YES |     | NULL    |      |

+----------+-------------+------+-----+---------+-------+

3 rows in set (0.01 sec)

--主键id自动增长

mysql> drop table if exists teacher;

Query OK, 0 rows affected (0.32 sec)

mysql> create table teacher(id intprimary key auto_increment,

-> name varchar(20),

-> birthday date);

Query OK, 0 rows affected (0.96 sec)

mysql> desc teacher;

+----------+-------------+------+-----+---------+----------------+

| Field   | Type        | Null | Key |Default | Extra          |

+----------+-------------+------+-----+---------+----------------+

| id      | int(11)     | NO   | PRI | NULL    | auto_increment |

| name    | varchar(20) | YES  |     | NULL   |                |

| birthday | date        | YES |     | NULL    |                |

+----------+-------------+------+-----+---------+----------------+

3 rows in set (0.01 sec)

mysql> insert into teacher(name,birthday)values('jack','1992-02-12');

Query OK, 1 row affected (0.06 sec)

mysql> insert intoteacher(name,birthday) values('marry','1992-4-8');

Query OK, 1 row affected (0.09 sec)

mysql> insert intoteacher(name,birthday) values('arry','1982-4-8');

Query OK, 1 row affected (0.14 sec)

mysql> select * from teacher;

+----+-------+------------+

| id | name | birthday   |

+----+-------+------------+

|  1| jack  | 1992-02-12|

|  2| marry | 1992-04-08 |

|  3| arry  | 1982-04-08|

+----+-------+------------+

3 rows in set (0.00 sec)

--检查主键id增长的序列

mysql> delete from teacher whereid<=3;

Query OK, 3 rows affected (0.08 sec)

mysql> select * from teacher;

Empty set (0.00 sec)

mysql> insert intoteacher(name,birthday) values('jack','1992-02-12');

Query OK, 1 row affected (0.13 sec)

mysql> select * from teacher;

+----+------+------------+

| id | name | birthday   |

+----+------+------------+

|  4| jack | 1992-02-12 |

+----+------+------------+

1 row in set (0.00 sec)

--多人项目中,通常使用UUID来生成唯一的主键值,便于多个合并数据时依然保持实体完整性

4 唯一约束的特点

(1)非NULL值不能重复

(2)可以插入多个NULL值

(3)'NULL'空串和NULL是不同的概念

mysql> drop table teacher;

Query OK, 0 rows affected (0.42 sec)

--唯一

mysql> create table teacher(id intprimary key auto_increment,

-> name varchar(20) unique,

-> birthday date);

Query OK, 0 rows affected (1.49 sec)

mysql> insert intoteacher(name,birthday) values('marry','2011-2-2');

Query OK, 1 row affected (0.11 sec)

mysql> insert intoteacher(name,birthday) values(NULL,'2011-1-1');

Query OK, 1 row affected (0.04 sec)

mysql> desc teacher;

+----------+-------------+------+-----+---------+----------------+

| Field   | Type        | Null | Key |Default | Extra          |

+----------+-------------+------+-----+---------+----------------+

| id      | int(11)     | NO   | PRI | NULL    | auto_increment |

| name    | varchar(20) | YES  | UNI | NULL   |                |

| birthday | date        | YES |     | NULL    |                |

+----------+-------------+------+-----+---------+----------------+

3 rows in set (0.00 sec)

--违反唯一

mysql> insert intoteacher(name,birthday) values('marry','2011-2-2');

ERROR 1062 (23000): Duplicate entry 'marry'for key 'name'

5 非空约束特点

(1)不能插入NULL值

(2)主键约束=非NULL约束+唯一约束

--违返不为空约束

mysql> drop table if exists teacher;

Query OK, 0 rows affected (0.19 sec)

mysql> create table teacher(

->    id int primary keyauto_increment,

->    name varchar(20) not nullunique,

->    birthday date

-> );

Query OK, 0 rows affected (1.45 sec)

mysql> insert intoteacher(name,birthday) values(NULL,'2011-1-1');

ERROR 1048 (23000): Column 'name' cannot benull

6 外健特点

(1)外键值必须来源于所引用别一个表主键值,或NULL

*7 关联关系

(1)一对一(外健根业务有关)

(2)一对多或多对一(外键放置在多方)

(3)多对多(外健放置在关联表中,即将一个多对多拆分成二个一对多关系)

一对一关系一:

mysql> create table person(

->  id int primary keyauto_increment,

->  name varchar(20) not null

-> );

Query OK, 0 rows affected (1.16 sec)

mysql> insert into person(name)values('jack');

Query OK, 1 row affected (0.15 sec)

mysql> insert into person(name)values('marry');

Query OK, 1 row affected (0.06 sec)

--card中pid为外person的外键

mysql> create table card(

-> id int primary key auto_increment,

->  location varchar(20) notnull,

->  pid int,

->  constraint pid_FK foreignkey(pid) references person(id)

-> );

Query OK, 0 rows affected (1.55 sec)

mysql> insert into card(location,pid)values('BJ',1);

Query OK, 1 row affected (0.11 sec)

mysql> insert into card(location,pid)values('GZ',2);

Query OK, 1 row affected (0.39 sec)

--外键pid可以插入NULL

mysql> insert into card(location,pid)values('CS',NULL);

Query OK, 1 row affected (0.05 sec)

--显示person与card表中的数据

mysql> select * from person;

+----+-------+

| id | name |

+----+-------+

|  1| jack  |

|  2| marry |

+----+-------+

2 rows in set (0.00 sec)

mysql> select * from card;

+----+----------+------+

| id | location | pid  |

+----+----------+------+

|  1| BJ       |    1 |

|  2| GZ       |    2 |

|  3| CS       | NULL |

+----+----------+------+

3 rows in set (0.00 sec)

--插入pid为3的出错误,外键pid必须来源另一表的主键值或为NULL

mysql> insert into card(location,pid)values('NJ',3);

ERROR 1452 (23000): Cannot add or update achild row: a foreign key constraint fails (`mydb2`.`card`, CONSTRAINT `pid_FK`FOREIGN KEY (`pid`) REFERENCES `person` (`id`))

注意:外键值必须来源于所引用别一个表主键值,或NULL

--有外键关系的行不能删除,需先删除其关联的外键关系,再进行删除主键关系的数据,与创建的时候相反

mysql> deletefrom person where name='jack';

ERROR 1451(23000): Cannot delete or update a parent row: a foreign key constraint fails(`mydb2`.`card`, CONSTRAINT `pid_FK` FOREIGN KEY (`pid`) REFERENCES `person`(`id`))

一对一关系方式二:主键当作另一个表的外键

例下面的card表的id既是主键又是外键

mysql> drop table if exists card;

Query OK, 0 rows affected (0.22 sec)

mysql> drop table if exists person;

Query OK, 0 rows affected (0.22 sec)

mysql> create table person(

-> id int primary key auto_increment,

->  name varchar(20) not null

-> );

Query OK, 0 rows affected (0.90 sec)

mysql> insert into person(name)values('jack');

Query OK, 1 row affected (0.07 sec)

mysql> insert into person(name)values('marry')

-> ;

Query OK, 1 row affected (0.10 sec)

--使用主键作为外键

mysql> create table card(

->  id int primary keyauto_increment,

->  location varchar(20) notnull,

->  constraint id_FK foreignkey(id) references person(id)

-> );

Query OK, 0 rows affected (0.86 sec)

mysql> insert into card(location)values('BJ');

Query OK, 1 row affected (0.06 sec)

mysql> insert into card(location)values('CS');

Query OK, 1 row affected (0.18 sec);

--id为3, 不符合参照完整性,3在person表中打不到

mysql> insert into card(location) values('GZ');

ERROR 1452 (23000): Cannot add or update achild row: a foreign key constraint fails (`mydb2`.`card`, CONSTRAINT `id_FK`FOREIGN KEY (`id`) REFERENCES `person` (`id`))

--NULL也不行,因为这里id为一个非空的属性

mysql> insert into card(location)values(NULL);

ERROR 1048 (23000): Column 'location'cannot be null

==========================一对多关系=============================

设计方案:

一方做一个容器,多方做一个引用

mysql> create table department(

->  id int primary keyauto_increment,

->  name varchar(20) not null

-> );

Query OK, 0 rows affected (1.70 sec)

mysql> insert into department(name)values('软件部');

Query OK, 1 row affected (0.10 sec)

mysql> insert into department(name)values('销售部');

Query OK, 1 row affected (0.06 sec)

mysql> create table employee(

->  id int primary keyauto_increment,

->  name varchar(20) not null,

->  did int,

->  constraint did_FK foreignkey(did) references department(id)

-> );

Query OK, 0 rows affected (1.02 sec)

mysql> insert into employee(name,did)values('jack',1);

Query OK, 1 row affected (0.12 sec)

mysql> insert into employee(name,did)values('marry',1);

Query OK, 1 row affected (0.13 sec)

mysql>

mysql> select * from department;

+----+-----------+

| id | name      |

+----+-----------+

|  1| 软件部    |

|  2| 销售部    |

+----+-----------+

2 rows in set (0.00 sec)

mysql> select * from employee;

+----+-------+------+

| id | name | did  |

+----+-------+------+

|  1| jack  |    1 |

|  2| marry |    1 |

+----+-------+------+

2 rows in set (0.00 sec)

--查询软件部的员工(利用子查询)

mysql> select * from employee wheredid=(select id from department where name='软件部');

+----+-------+------+

| id | name | did  |

+----+-------+------+

|  1| jack  |    1 |

|  2| marry |    1 |

+----+-------+------+

2 rows in set (0.05 sec)

--利用多表查询

mysql> select e.name as 员工姓名,d.name  as 部门名称 from employee e,department d where d.name='软件部';

+--------------+--------------+

| 员工姓名     | 部门名称     |

+--------------+--------------+

| jack         | 软件部       |

| marry        | 软件部       |

+--------------+--------------+

2 rows in set (0.01 sec)

============================多对多方案=============================

--创建的时候,先创建两边的,再创建中间的

--删除的时候先删除中间的,再删除两边的

mysql> drop table if exists middle;

Query OK, 0 rows affected, 1 warning (0.00sec)

mysql> drop table if exists student;

Query OK, 0 rows affected (0.25 sec)

mysql> drop table if exists teacher;

Query OK, 0 rows affected (0.33 sec)

mysql> create table if not existsstudent(

->  id int primary keyauto_increment,

->  name varchar(20) not null

-> );

Query OK, 0 rows affected (1.19 sec)

mysql> insert into student(name)values('jack');

Query OK, 1 row affected (0.08 sec)

mysql> insert into student(name)values('marry');

Query OK, 1 row affected (0.04 sec)

mysql> create table if not existsteacher(

->  id int primary key auto_increment,

->  name varchar(20) not null

-> );

Query OK, 0 rows affected (1.43 sec)

mysql> insert into teacher(name)values('赵');

Query OK, 1 row affected (0.34 sec)

mysql> insert into teacher(name)values('蔡');

Query OK, 1 row affected (0.07 sec)

--多对多(外健放置在关联表中,即将一个多对多拆分成二个一对多关系)

-- 组合主键

mysql> create table if not existsmiddle(

->  sid int,

->  tid int,

->  constraint sid_FK foreignkey(sid) references student(id),

->  constraint tid_FK foreignkey(tid) references teacher(id),

->  primary key(sid,tid)

-> );

Query OK, 0 rows affected (1.59 sec)

mysql> insert into middle(sid,tid)values(1,1);

Query OK, 1 row affected (0.14 sec)

mysql> insert into middle(sid,tid)values(1,2);

Query OK, 1 row affected (0.06 sec)

mysql> insert into middle(sid,tid)values(2,1);

Query OK, 1 row affected (1.07 sec)

mysql> insert into middle(sid,tid)values(2,2);

Query OK, 1 row affected (0.07sec)mysql> insert into middle(sid,tid) values(2,2);

--查询赵教师教过的所有学员,组合查询

--t.name='赵'  条件

-- and m.sid=s.id andm.tid=t.id  --表连接起来

模式:

select 列出需要显示的字段

from 列出所涉及到的所有表,建议写别名

where 业务条件and 表关联条件

--sql

mysql> selectt.name as 老师, s.name as 学员

-> from teacher as t,student as s,middleas m

-> where t.name = '赵'and m.sid=s.id and m.tid=t.id;

+--------+--------+

| 老师  | 学员   |

+--------+--------+

| 赵    | jack   |

| 赵    | marry  |

+--------+--------+

2 rows in set(0.00 sec)

Mysql表的约束设计和关联关系设计的更多相关文章

  1. Python进阶----数据库引擎(InnoDB),表的创建,mysql的数据类型,mysql表的约束

    Python进阶----数据库引擎(InnoDB),表的创建,mysql的数据类型,mysql表的约束 一丶MySQL的存储引擎 什么是存储引擎:    MySQL中的数据用各种不同的技术存储在文件( ...

  2. MySql表、约束、视图

    MySql表.约束.视图 索引组织表 在InnoDB存储引擎中,表都是根据主键顺序组织存放的,这种存储方式的表成为索引组织表(index organized table). 每张表都有主键,如果创建表 ...

  3. MySQL 表的约束与数据库设计

    DQL 查询语句 排序 # 单列排序 * 只按某一个字段进行排序,单列排序 # 组合排序 * 同时对多个字段进行排序,如果第1个字段相等,则按照第2个字段排序,依次类推 * 语法: # 具体操作 * ...

  4. MySQL表级约束和列级约束

    对一个数据列建立的约束,称为列级约束 对多个数据列建立的约束,称为表级约束 列级约束即可以在列定义时生命,也可以在列定义后声明. 表级约束只能在列定义后声明. NOT NULL和DEFAULT只存在列 ...

  5. mysql表设计注意点

    [原创]面试官:讲讲mysql表设计要注意啥 需要设计一个主键 因为你不设主键的情况下,innodb也会帮你生成一个隐藏列,作为自增主键.所以啦,反正都要生成一个主键,那你还不如自己指定一个主键,在有 ...

  6. 面试mysql表设计要注意啥

    面试官:讲讲mysql表设计要注意啥? 引言 大家应该知道烟哥最近要(tiao 咳咳咳),嗯,不可描述! 随手讲其中一部分知识,都是一些烟哥自己平时工作的总结以及经验.大家看完,其实能避开很多坑.而且 ...

  7. Java连接MySQL数据库。编写一个应用程序,在主类Test_4类中,通过JDBC访问stu数据库,显示t_student表中的内容(表结构见表1),显示效果自己设计。

    题目2:编写一个应用程序,在主类Test_4类中,通过JDBC访问stu数据库,显示t_student表中的内容(表结构见表1),显示效果自己设计.之后,可根据显示的内容进行某条记录的删除(以id为条 ...

  8. 一、TCL事务控制语言 二、MySQL中的约束 三、多表查询(重点) 四、用户的创建和授权 五、MySQL中的索引

    一.TCL事务控制语言###<1>事务的概念 事务是访问并可能更新数据库中各种数据项的执行单元. 事务是一条SQL语句,一组SQL语句,或者整个程序. 事务是恢复和并发控制的基本单位. 事 ...

  9. MySQL数据分析-(6)数据库设计之规范化

    大家好,我是jacky,很高兴继续跟大家学习MySQL数据分析这门课,上次课我们介绍了E-R图,我们要给手机销售公司设计数据库,那么同一个项目,10个设计人员可能设计出10种不同的E-R图:因为不同的 ...

随机推荐

  1. 【opencv实践】边缘检测

    边缘检测: 一.canny算子 Canny边缘检测根据对信噪比与定位乘积进行测度,得到最优化逼近算子,也就是Canny算子.类似与 LoG 边缘检测方法,也属于先平滑后求导数的方法. 二.canny算 ...

  2. golang _下划线占位符代替需要释放的资源的问题

    golang中_有两种作用,一种用在import中,比如这样 import _ "github.com/go-sql-driver/mysql" 表示并不需要导入整个包,只是执行这 ...

  3. JAVA进阶17

    ---恢复内容开始--- 间歇性混吃等死,持续性踌躇满志系列-------------第17天 1.递归结构 递归是一种常见的解决问题的方法,即把问题逐渐简单化.递归的基本思想就是自己就是“自己调用自 ...

  4. 题解 洛谷P3936 Coloring

    考虑搜索,发现复杂度爆炸        贪心,正确性过低(~~实测爆炸~~) 于是,~~发现~~这题是模拟退火 这里不讲解退火的定义了,初学退火可以去平衡点 退火本身维护一个答案图像,答案的q,当前图 ...

  5. HDU - 1062

    格式错误2遍:没考虑到连续两个空格的情况,遇到空格最后要输出这个空格,因为题目只需要转换单词. 另外,开cin,cout加速要注意读入不能用scanf,printf,puts,getchar这些.ge ...

  6. YOLO v3

    yolo为you only look once. 是一个全卷积神经网络(FCN),它有75层卷积层,包含跳跃式传递和降采样,没有池化层,当stide=2时用做降采样. yolo的输出是一个特征映射(f ...

  7. 项目Alpha冲刺(1/10)

    1.项目燃尽图 2.今日进度描述 项目进展 熟悉Android Studio的基本使用,阅读代码规范 问题困难 学习中存在许多问题. 心得体会 应该选择一个自己熟悉的平台进行开发. 3.会议照片 4. ...

  8. 通过hook实现禁止shift+delete快捷键

    实现全局hook必须要将hook代码封装在dll里,所以此程序有两个文件:noShiftDeleteHook.dll和noShiftDelete.exe noShiftDeleteHook.dll / ...

  9. java学习笔记05-运算符

    算数运算符 +:相加 -:相减 *:相乘 /:相除 %:取余 ++:自增 --:自减 public static void main(String[] args) { int i = 10; int ...

  10. 从koa-session源码解读session本质

    前言 Session,又称为"会话控制",存储特定用户会话所需的属性及配置信息.存于服务器,在整个用户会话中一直存在. 然而: session 到底是什么? session 是存在 ...