设置在表头上,作用,控制表头赋值的
primary key
表头不能赋null值且值唯一
mysql> create table db3.t7( 姓名 char(3),age int default 19,身份证 char(18),primary key(身份证) );
mysql> create table db3.t8( 姓名 char(3),age int default 19,身份证 char(18) primary key );
mysql> desc db3.t7;
+-----------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+----------+------+-----+---------+-------+
| 姓名 | char(3) | YES | | NULL | |
| age | int | YES | | 19 | |
| 身份证 | char(18) | NO | PRI | NULL | |
+-----------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> desc db3.t8;
+-----------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+----------+------+-----+---------+-------+
| 姓名 | char(3) | YES | | NULL | |
| age | int | YES | | 19 | |
| 身份证 | char(18) | NO | PRI | NULL | |
+-----------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> alter table db3.t8 drop primary key;
Query OK, 0 rows affected (1.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc db3.t8;
+-----------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+----------+------+-----+---------+-------+
| 姓名 | char(3) | YES | | NULL | |
| age | int | YES | | 19 | |
| 身份证 | char(18) | NO | | NULL | |
+-----------+----------+------+-----+---------+-------+
3 rows in set (0.01 sec)
mysql> alter table db3.t8 modify 身份证 char(18);
Query OK, 0 rows affected (0.80 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc db3.t8;
+-----------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+----------+------+-----+---------+-------+
| 姓名 | char(3) | YES | | NULL | |
| age | int | YES | | 19 | |
| 身份证 | char(18) | YES | | NULL | |
+-----------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> alter table db3.t8 add primary key(身份证);
Query OK, 0 rows affected (0.83 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc db3.t8;
+-----------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+----------+------+-----+---------+-------+
| 姓名 | char(3) | YES | | NULL | |
| age | int | YES | | 19 | |
| 身份证 | char(18) | NO | PRI | NULL | |
+-----------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> insert into db3.t8(姓名,身份证) values("张三","1111"); # 正常
mysql> insert into db3.t8(姓名,身份证) values("张五","2222"); # 正常
mysql> insert into db3.t8(姓名,身份证) values("张五",null); # 空 报错
mysql> insert into db3.t8(姓名,身份证) values("张六","2222"); # 重复 报错
多个表头一起做主键 必须一起创建或删除
表头的值不同时重复即可
mysql> desc db3.t9;
mysql> create table db3.t9(
-> cip varchar(15),
-> port int,
-> status enum("allow","deny"),
-> primary key(cip,port)
-> );
Query OK, 0 rows affected (0.39 sec)
mysql> alter table db3.t9 drop primary key;
mysql> alter table db3.t9 add primary key(cip,port);
mysql> insert into db3.t9 values("1.1.1.1",22,"allow");
Query OK, 1 row affected (0.04 sec)
mysql> insert into db3.t9 values("1.1.1.1",22,"deny");
ERROR 1062 (23000): Duplicate entry '1.1.1.1-22' for key 't9.PRIMARY'
mysql> insert into db3.t9 values("1.1.1.1",80,"allow");
Query OK, 1 row affected (0.08 sec)
自增长
给表头加了自增长的设置后 不给表头赋值时 通过自加1的计算结果赋值
自增长必须和主键
mysql> create table db3.t10(
-> mun int primary key auto_increment,
-> name char(3),
-> age int
-> );
Query OK, 0 rows affected (1.00 sec)
mysql> desc db3.t10;
+-------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+----------------+
| mun | int | NO | PRI | NULL | auto_increment |
| name | char(3) | YES | | NULL | |
| age | int | YES | | NULL | |
+-------+---------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
mysql> insert into db3.t10(name,age) values("b",21);
Query OK, 1 row affected (0.04 sec)
mysql> insert into db3.t10(name,age) values("a",21);
Query OK, 1 row affected (0.09 sec)
mysql> select * from db3.t10;
+-----+------+------+
| mun | name | age |
+-----+------+------+
| 1 | b | 21 |
| 2 | a | 21 |
+-----+------+------+
2 rows in set (0.00 sec)
删除
mysql> desc db3.t10;
+-------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+----------------+
| mun | int | NO | PRI | NULL | auto_increment |
| name | char(3) | YES | | NULL | |
| age | int | YES | | NULL | |
+-------+---------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
mysql> alter table db3.t10 modify mun int;
mysql> desc db3.t10;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| mun | int | NO | PRI | NULL | |
| name | char(3) | YES | | NULL | |
| age | int | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> alter table db3.t10 drop primary key;
mysql> desc db3.t10;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| mun | int | NO | | NULL | |
| name | char(3) | YES | | NULL | |
| age | int | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
3 rows in set (0.00 sec)
给外键表头赋值时,值在参考的表的主键表头值里选择
salary.employee_id 外键 ----参考-----> employees.employee_id
# 表头类型 存储引擎
create table 库.表(
表头名列表,
foreign key(表a的表头名) references 库.表b(表b的表头名)
)engine=innodb;
create table 库.表(
表头名列表,
foreign key(表a的表头名) references 库.表b(表b的表头名)
on update cascade on delete cascade
);
mysql> create table db3.yg_tab( yg_id int primary key auto_increment, name char(4) );
mysql> insert into db3.yg_tab(name) values("tom"),("lucy"),("lili");
mysql> select * from db3.yg_tab;
mysql> create table db3.gz_tab( gz_id int , 工资 float, foreign key(gz_id) references db3.yg_tab(yg_id) on update cascade on delete cascade )engine=innodb;
mysql> show create table db3.gz_tab\G
*************************** 1. row ***************************
Table: gz_tab
Create Table: CREATE TABLE `gz_tab` (
`gz_id` int DEFAULT NULL,
`工资` float DEFAULT NULL,
KEY `gz_id` (`gz_id`),
CONSTRAINT `gz_tab_ibfk_1` FOREIGN KEY (`gz_id`) REFERENCES `yg_tab` (`yg_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
mysql> alter table db3.gz_tab drop foreign key gz_tab_ibfk_1;
Query OK, 0 rows affected (0.14 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table db3.gz_tab\G
*************************** 1. row ***************************
Table: gz_tab
Create Table: CREATE TABLE `gz_tab` (
`gz_id` int DEFAULT NULL,
`工资` float DEFAULT NULL,
KEY `gz_id` (`gz_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
mysql> alter table db3.gz_tab add foreign key(gz_id) references db3.yg_tab(yg_id) on update cascade on delete cascade;
Query OK, 0 rows affected (0.74 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table db3.gz_tab\G *************************** 1. row ***************************
Table: gz_tab
Create Table: CREATE TABLE `gz_tab` (
`gz_id` int DEFAULT NULL,
`工资` float DEFAULT NULL,
KEY `gz_id` (`gz_id`),
CONSTRAINT `gz_tab_ibfk_1` FOREIGN KEY (`gz_id`) REFERENCES `yg_tab` (`yg_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
mysql> select * from db3.yg_tab;
+-------+------+
| yg_id | name |
+-------+------+
| 1 | tom |
| 2 | lucy |
| 3 | lili |
+-------+------+
3 rows in set (0.00 sec)
mysql> select * from db3.gz_tab;
Empty set (0.00 sec)
mysql> desc db3.gz_tab;
+--------+-------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------+------+-----+---------+-------+
| gz_id | int | YES | MUL | NULL | |
| 工资 | float | YES | | NULL | |
+--------+-------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> insert into db3.gz_tab values(1,10000);
Query OK, 1 row affected (0.07 sec)
mysql> insert into db3.gz_tab values(2,20000);
Query OK, 1 row affected (0.06 sec)
mysql> insert into db3.gz_tab values(3,30000);
Query OK, 1 row affected (0.10 sec)
# 没有的4号员工 工资表插入记录报错
mysql> insert into db3.gz_tab values(4,40000);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`db3`.`gz_tab`, CONSTRAINT `gz_tab_ibfk_1` FOREIGN KEY (`gz_id`) REFERENCES `yg_tab` (`yg_id`) ON DELETE CASCADE ON UPDATE CASCADE)
# 员工表 插入编号4的员工
mysql> insert into db3.yg_tab(name) values("bob");
Query OK, 1 row affected (0.04 sec)
# 可以给4号员工 发工资了
mysql> insert into db3.gz_tab values(4,40000);
Query OK, 1 row affected (0.04 sec)
mysql> select * from db3.yg_tab;
+-------+------+
| yg_id | name |
+-------+------+
| 1 | tom |
| 2 | lucy |
| 3 | lili |
| 4 | bob |
+-------+------+
4 rows in set (0.00 sec)
mysql> select * from db3.gz_tab;
+-------+--------+
| gz_id | 工资 |
+-------+--------+
| 1 | 10000 |
| 2 | 20000 |
| 3 | 30000 |
| 4 | 40000 |
+-------+--------+
4 rows in set (0.00 sec)
mysql> update db3.yg_tab set yg_id=8 where yg_id=4;
Query OK, 1 row affected (0.05 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from db3.yg_tab;
+-------+------+
| yg_id | name |
+-------+------+
| 1 | tom |
| 2 | lucy |
| 3 | lili |
| 8 | bob |
+-------+------+
4 rows in set (0.00 sec)
mysql> select * from db3.gz_tab;
+-------+--------+
| gz_id | 工资 |
+-------+--------+
| 1 | 10000 |
| 2 | 20000 |
| 3 | 30000 |
| 8 | 40000 |
+-------+--------+
4 rows in set (0.01 sec)
mysql> delete from db3.yg_tab where yg_id=2;
Query OK, 1 row affected (0.07 sec)
mysql> select * from db3.yg_tab;
+-------+------+
| yg_id | name |
+-------+------+
| 1 | tom |
| 3 | lili |
| 8 | bob |
+-------+------+
3 rows in set (0.00 sec)
mysql> select * from db3.gz_tab;
+-------+--------+
| gz_id | 工资 |
+-------+--------+
| 1 | 10000 |
| 3 | 30000 |
| 8 | 40000 |
+-------+--------+
3 rows in set (0.00 sec)
# 被参考的表不能删除
mysql> drop table db3.yg_tab;
ERROR 3730 (HY000): Cannot drop table 'yg_tab' referenced by a foreign key constraint 'gz_tab_ibfk_1' on table 'gz_tab'.
mysql>
给 db3.gz_tab 表的 gz_id 表头 加主键标签
保证每个员工只能发1遍工资 且有员工编号的员工才能发工资
# 如果重复发工资和没有编号的发了工资 删除记录后 再添加主键
mysql> insert into db3.gz_tab values(1,70000);
mysql> insert into db3.gz_tab values(null,80000);
mysql> select * from db3.gz_tab;
+-------+--------+
| gz_id | 工资 |
+-------+--------+
| 1 | 10000 |
| 3 | 30000 |
| 8 | 40000 |
| 1 | 70000 |
| NULL | 80000 |
+-------+--------+
5 rows in set (0.00 sec)
mysql> delete from db3.gz_tab;
mysql> alter table db3.gz_tab add primary key(gz_id);
保证每个员工只能发1遍工资 且有员工编号的员工才能发工资
mysql> desc db3.gz_tab;
+--------+-------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------+------+-----+---------+-------+
| gz_id | int | NO | PRI | NULL | |
| 工资 | float | YES | | NULL | |
+--------+-------+------+-----+---------+-------+
2 rows in set (0.00 sec)
索引是数据结构 类似于书的目录 设置在表头上 给表头下存储的数据 生成排队
信息 保存在表对应的文件里(/var/lib/mysql/库名/表名.ibd)
给表头 加索引的目的 为了加快 查找数据的速度
Hash Btree(二杈树`) B+tree
mysql> create table db3.t61( name char(3), age int, sex enum("boy","girl"), index(name),index(sex) );
MUL
mysql> desc db3.t61;
+-------+--------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------------+------+-----+---------+-------+
| name | char(3) | YES | MUL | NULL | |
| age | int | YES | | NULL | |
| sex | enum('boy','girl') | YES | MUL | NULL | |
+-------+--------------------+------+-----+---------+-------+
3 rows in set (0.01 sec)
mysql> show index from db3.t61;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| t61 | 1 | name | 1 | name | A | 0 | NULL | NULL | YES | BTREE | | | YES | NULL |
| t61 | 1 | sex | 1 | sex | A | 0 | NULL | NULL | YES | BTREE | | | YES | NULL |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
2 rows in set (0.01 sec)
Key_name:索引名(默认索引名和表头名相同)
drop index 索引名 on db3.t61;
mysql> drop index sex on db3.t61;
create index 索引名 on db3.t61(表头);
mysql> create index sex on db3.t61(sex);
mysql> desc db3.user;
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| name | varchar(20) | YES | | NULL | |
| password | char(1) | YES | | NULL | |
| uid | int | YES | | NULL | |
| gid | int | YES | | NULL | |
| comment | varchar(200) | YES | | NULL | |
| homedir | varchar(30) | YES | | NULL | |
| shell | varchar(30) | YES | | NULL | |
+----------+--------------+------+-----+---------+----------------+
8 rows in set (0.00 sec)
使用name表头做筛选条件,查找记录
mysql> select * from db3.user where name="sshd";
+----+------+----------+------+------+-------------------------+-----------------+---------------+
| id | name | password | uid | gid | comment | homedir | shell |
+----+------+----------+------+------+-------------------------+-----------------+---------------+
| 21 | sshd | x | 74 | 74 | Privilege-separated SSH | /var/empty/sshd | /sbin/nologin |
+----+------+----------+------+------+-------------------------+-----------------+---------------+
1 row in set (0.00 sec)
验证是否使用索引
mysql> explain select * from db3.user where name="sshd" \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: user
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 24
filtered: 10.00
Extra: Using where
1 row in set, 1 warning (0.01 sec)
查看表的总行数,查找sshd 用做的是全表扫描
mysql> select count(*) from db3.user;
+----------+
| count(*) |
+----------+
| 24 |
+----------+
1 row in set (0.00 sec)
给name表头设置索引
mysql> create index name on db3.user(name);
Query OK, 0 rows affected (0.28 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc db3.user;
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| name | varchar(20) | YES | MUL | NULL | |
| password | char(1) | YES | | NULL | |
| uid | int | YES | | NULL | |
| gid | int | YES | | NULL | |
| comment | varchar(200) | YES | | NULL | |
| homedir | varchar(30) | YES | | NULL | |
| shell | varchar(30) | YES | | NULL | |
+----------+--------------+------+-----+---------+----------------+
8 rows in set (0.00 sec)
验证索引
mysql> explain select * from db3.user where name="sshd" \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: user # 表名
partitions: NULL
type: ref
possible_keys: name
key: name # 使用的索引名
key_len: 83
ref: const
rows: 1 # 查找的总行数
filtered: 100.00
Extra: NULL # 额外说明
1 row in set, 1 warning (0.00 sec)
衡量表创建的是否合理的标准
1NF 表头要满足原子性
2NF 1NF + 2NF(表里一定要有主键)
3NF 1NF + 2NF + 3NF(表头下的数据不能有传递依赖)
授权是在数据库服务器里添加用户并设置权限及密码
重复执行grant命令时如果库名和用户名不变时,是追加权限
在数据库服务器里 添加用户 并授予权限,添加的用户是给网站连接数据库用的
create user 用户名@"客户端地址" identified by "密码";
mysql> create user admin@"%" identified by "123456";
grant 权限列表 on 库名.表名 to 用户名@"客户端地址";
mysql> grant all on *.* to admin@"%";
mysql库 存储用户权限信息,主要表如下:
user表 保存已有的授权用户及用户对所有库的权限
db表 保存已有授权用户对某一个库的访问权限
tables_priv表 记录已有授权用户对某一张表的访问权限
columns_priv表 记录已有授权用户对某一个表头的访问权限
查看表记录可以获取用户权限
也可以更新记录达到修改用户权限的目的
ALL 所有权限
USAGE 无权限
SELECT,UPDATE,INSERT 个别权限
SELECT,UPDATE(字段1,字段N) 指定字段
*.* 所有库所有表
库名.* 一个库
库名.表名 一张表
授权时自定义 要有标识性
存储在mysql库的user表里
客户端地址
% 所有主机
192.168.88.% 网段内的所有主机
192.168.88.52 固定1台主机
localhost 数据库服务器本机
mysql -h数据库服务器ip/地址 [-P端口号] -u用户名 -p密码
[root@mysql51 ~]# mysql -h192.168.88.50 -uadmin -p123456 -P3306
mysql> select user(); # 查看登录的用户
mysql> show grants; # 查看访问权限
[root@mysql50 ~]# mysql -p123456
mysql> create user webuser@"192.168.88.51" identified by "123456";
mysql> grant select on tarena.* to webuser@"192.168.88.51";
mysql> grant insert,update,delete on tarena.* to webuser@"192.168.88.51";
[root@mysql51 ~]# mysql -h192.168.88.50 -uwebuser -p123456 -P3306
mysql> show grants;
创建的用户 和 授予权限 存放在哪里了
授权库 mysql库的表里了
mysql> desc mysql.user;
mysql> select user,host from mysql.user;
mysql> show grants for admin@"%";
mysql> show grants for webuser@"192.168.88.51";
mysql> select * from mysql.db \G
mysql> create user bb@"localhost" identified by "123456";
mysql> grant select,update(name) on tarena.user to bb@"localhost";
mysql> select user,host from mysql.user;
mysql> select * from mysql.columns_priv;