文章目录
mysql:关系型数据库
一、如何使用终端操作操作数据库?
1、如何登陆数据库服务器?
先前已经在系统的环境变量中配置过了数据库,使用win10操作系统,调出cmd
输入:
C:\Windows\system32> net start mysql
用来启动数据库
C:\Windows\system32> mysql -uroot -p
用来登陆数据库,回车后输入密码可进入数据库
mysql> exit
用来退出数据库(命令用大写和小写都可以,关键字一般都大写)
2 、如何查询数据库服务器中所有数据库?
输入 mysql> show databases;
注意最后的分号 ; 不要丢
3、如何选中某一个数据库进行操作?
数据库服务器中有自己创建的很多数据库,如何选中自己想要处理的数据库
mysql> use test;
我们就选中了这个数据库.
如果不选中某个数据库,就对数据库使用SQL语句操作的话,会出现错误No database selected
mysql> use test; 通过这个语句选中某个数据库
mysql> select * from admin 通过SQL查询 语句可以查看数据库中admin表中的内容。
4. 创建删除数据库
创建一个数据库 create database +‘数据库名字’ + character set utf8
mysql> create database 'test' character set utf8;
- 其中的character set utf8 用来设定编码,可以防止数据出现乱码*
- 注意这里 数据库的名字 用键盘上Esc下面那个在英文模式下的单引号括起来!!!
删除一个数据库 drop databases + 数据库的名字 ;
mysql> drop databases test;
删除我们刚才创建的表
注意删除时数据库不要用单引号括起来!!!
5. 数据表
- 查看一下我们这个数据库里面的表
mysql> show tables;
显然结果是:Empty set (0.00 sec)
里面没有表 - 创建一个数据表
mysql> CREATE TABLE pet ( #其中pet是数据表的名字,括号内是数据字段name、owner...
name VARCHAR(20), #VARCHAR是字符类型
owner VARCHAR(20), #括号内是限制字符个数
species VARCHAR(20),
sex CHAR(1),
birth DATE,
death DATE);
表就创建好了,再 show table;可以看到我们创建的表。
- 查看数据表的结构
mysql> describe pet;
其中describe可以简写成desc - 查看数据表中的记录
mysql> select * from pet;
#selsct表示查询,*表示所有,from指查询的表
由于刚才创建表但是没在表中添加数据,所以返回时空的Empty set (0.00 sec)
- 向数据表中添加数据记录,方法为
INSERT INTO + 表名
mysql> INSERT INTO pet
-> VALUES('xiaoming','father','human','m','1999-01-23',NULL); #按照数据字段的顺序输入
Query OK, 1 row affected (0.73 sec) 说明执行成功
OK~添加成功,再 select * from pet ;看一眼,发现添加进去了
再添加一个元素,实验一下。
mysql> INSERT INTO pet
-> VALUES('蔡徐坤','篮球','人','男','1998-08-08',NULL);
Query OK, 1 row affected (0.63 sec)
mysql> select * from pet;
+-----------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+-----------+--------+---------+------+------------+-------+
| xiaoming | father | human | m | 1999-01-23 | NULL |
| 蔡徐坤 | 篮球 | 人 | 男 | 1998-08-08 | NULL |
+-----------+--------+---------+------+------------+-------+
2 rows in set (0.00 sec)
6. mysql常用的数据类型?
mysql支持多种类型,大致分为三类:数值、日期/时间、字符串(字符)类型。
参考
- 数值
一般用INT类型,FLOAT;DOUBLE。
#创建一个表
mysql> CREATE TABLE testType(
number TINYINT
);
Query OK, 0 rows affected (0.98 sec)
#添加内容(127在范围内)
mysql> INSERT INTO testType VALUES(127);
Query OK, 1 row affected (0.57 sec)
mysql> select * from testType;
+--------+
| number |
+--------+
| 127 |
+--------+
1 row in set (0.00 sec)
#当添加128时会报错,注意范围!
mysql> INSERT INTO testType VALUES (128);
ERROR 1264 (22003): Out of range value for column 'number' at row 1
- 日期
具体格式看菜鸟教程中的格式进行输入 - 字符串
参考菜鸟教程
常用的是:CHAR;VARCHAR;TEXT;
总之一句话:数值、字符串按照大小,日期时间按照格式.
7. 如何删除、修改数据?
- 向表中添加数据
INSERT INTO 表名 VALUES(按字段添加数据)
向刚才的pet表中添加数据:
INSERT INTO pet VALUES ('puffball', 'Diane', 'hamster', 'f', '1990-03-30', NULL);
INSERT INTO pet VALUES ('puffl', 'Dne', 'hster', 'f', '1999-08-30', NULL);
- 删除数据
mysql> delete from + 表 + where name=’ 要删除的数据
那一行数据就被删除了
mysql> delete from pet where name='王二娘';
Query OK, 2 rows affected (0.17 sec)
- 修改数据
假如我们要修改蔡徐坤的性别mysql> update pet set sex='雌' where name='蔡徐坤';
小结一下:数据记录的常见操作: (增删改查)
增加:INSERT
删除:DELETE
修改: UPDATE
查询:SELECT
二、mysql约束建表
约束包括:(主键约束、自增约束),(外键约束),(唯一约束),(非空约束),(默认约束)
1. 主键约束
它能够唯一确定一张表中的一条记录,也就是我们给某个字段添加约束,就可以使得该字段不重复且不为空。
MySQL主键(Primary Key)是唯一标识表中每行的列或一组列。当定义表的主键时,必须遵循以下规则:
- 主键必须包含唯一值。如果主键由多个列组成,则这些列中的值的组合必须是唯一的。
- 主键列不能包含NULL值。 这意味着必须使用NOT NULL属性声明主键列。如果没有指定NOT NULL,MySQL将强制为主键列为NOT NULL。
- 一张表只有一个主键。
CREATE TABLE user (
id INT PRIMARY KEY,
name VARCHAR(20)
);
测试:
mysql> create table user(
-> id int primary key, #添加一个主键约束
-> name varchar(20)
-> );
Query OK, 0 rows affected (0.88 sec)
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| pet |
| testtype |
| user |
+----------------+
3 rows in set (0.01 sec)
添加数据:
mysql> INSERT INTO user VALUES(1,'吴亦凡');
Query OK, 1 row affected (0.62 sec)
# 但是再输入相同的内容时,mysql会提示你重复了,因为有了主键约束!!
mysql> INSERT INTO user VALUES(1,'吴亦凡');
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
这样就可以添加了
mysql> INSERT INTO user VALUES(2,'吴亦凡');
Query OK, 1 row affected (0.17 sec)
# 改成2才可以
那么id可不可以为空呢?
mysql> INSERT INTO user VALUES(NULL,'吴亦凡');
ERROR 1048 (23000): Column 'id' cannot be null
当然不可以为空,主建约束目的就是:为了唯一确定一张表中的一条记录,id不可以为空。
2. 联合主键
联合主键中的每个字段都不能为空,并且加起来不能和已设置的联合主键重复。
CREATE TABLE user (
id INT,
name VARCHAR(20),
password VARCHAR(20),
PRIMARY KEY(id, name)
);
代码实验:
mysql> create table user2(
-> id int,
-> name varchar(20),
-> password varchar(20),
-> primary key (id,name)
-> );
Query OK, 0 rows affected (1.13 sec)
其中id和name只要他们两个加起来不重复就OK,例子如下:
mysql> insert into user2 values(1,'张三','123');
#给user2表添加数据
Query OK, 1 row affected (0.58 sec)
mysql> insert into user2 values(1,'张三','123');
#给user2表添加相同数据
ERROR 1062 (23000): Duplicate entry '1-张三' for key 'PRIMARY'
mysql> insert into user2 values(2,'张三','123');
#id和名字只要有一个不重复就行了
Query OK, 1 row affected (0.42 sec)
mysql> insert into user2 values(2,'李四','123');
Query OK, 1 row affected (0.55 sec)
mysql> select * from user2;
+----+--------+----------+
| id | name | password |
+----+--------+----------+
| 1 | 张三 | 123 |
| 2 | 张三 | 123 |
| 2 | 李四 | 123 |
+----+--------+----------+
3 rows in set (0.00 sec)
大家可以理解成 ‘’或‘’,注意 联合主键任何一个键都不能为空!!!
联合主键:就是用多个字段一起作为一张表的主键
这里引用一篇文章主键的唯一性和联合主键概念辨析这里面讲解了主键和的唯一性和联合主键的辨析。
3. 自增约束
自增约束的主键由系统自动递增分配。AUTO_INCREMENT
自增约束------就是管控id的增长。
- 当插入第一条记录时,自增字段没有给定一个具体值,可以不赋值 可以写成DEFAULT/NULL,那么以后插入字段的时候,该自增字段就是从1开始,每插入一条记录,该自增字段的值增加1。
- 当插入第一条记录时,给自增字段一个具体值,那么以后插入的记录在此自增字段上的值,就在第一条记录该自增字段的值的基础上每次增加1。
CREATE TABLE user (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(20)
);
代码实验:
mysql> create table user3(
-> id int primary key AUTO_INCREMENT,
-> name varchar(20)
-> );
Query OK, 0 rows affected (0.95 sec)
mysql> insert into user3(name) values('zhangsan'); #添加一个数据
Query OK, 1 row affected (0.63 sec)
mysql> select * from user3;
+----+----------+
| id | name |
+----+----------+
| 1 | zhangsan |
+----+----------+
1 row in set (0.00 sec) #这里发现默认给了id=1
mysql> insert into user3(name) values('zhangsan'); #再添加一个
Query OK, 1 row affected (0.71 sec)
mysql> select * from user3;
+----+----------+
| id | name |
+----+----------+
| 1 | zhangsan |
| 2 | zhangsan |
+----+----------+
2 rows in set (0.00 sec)
4. 修改主键
我们建表的时候忘记创建主键约束怎么办?
可以通过alter table +表+ add primary key (id);
添加主键
可以通过mysql> alter table +表+ drop primary key;
删除主键
可以通过ALTER TABLE user MODIFY id INT PRIMARY KEY;
修改主键
mysql> create table user4(
-> id int,
-> name varchar(20)
-> );
Query OK, 0 rows affected (0.90 sec)
mysql> desc user4;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(20) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.10 sec)
从上面可以看到主键是空的(key)
如果我们创建表的时候,创建了主键,那么在Key对应的那个中会显示PRI。
mysql> alter table user4 add primary key (id);
Query OK, 0 rows affected (1.40 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc user;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | varchar(20) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql>
删除主键
mysql> alter table user4 drop primary key;
Query OK, 0 rows affected (1.41 sec)
Records: 0 Duplicates: 0 Warnings: 0
5. 唯一约束
unique
约束修饰字段的值 不可以 重复
我们先创建一个表
mysql> create table user5( #创建表的时候没有给约束
-> id int,
-> name varchar(20)
-> );
Query OK, 0 rows affected (0.66 sec)
mysql> alter table user5 add unique(name); #添加一个唯一约束
除了先创表再添加约束,也可以在创表的时候就添加约束
mysql> create table user6(
-> id int,
-> name varchar(20),
-> unique(name)
-> );
Query OK, 0 rows affected (0.87 sec)
mysql> desc user6;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(20) | YES | UNI | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
其中name的key中的UNI表示name不可重复
可以像刚才那样,也可以这样:
mysql> create table user7(
-> id int,
-> name varchar(20) unique
-> );
但是这样只能设置一个唯一约束(或者在id int 后也加上unique)
mysql> create table user7(
-> id int,
-> name varchar(20),
-> unique(id,name)
-> );
Query OK, 0 rows affected (0.85 sec)
代码实验:
mysql> insert into user5 values(1,'zhangsan'); #添加一个数据
Query OK, 1 row affected (0.61 sec)
mysql> insert into user5 values(1,'zhangsan'); #不可以重复添加
ERROR 1062 (23000): Duplicate entry 'zhangsan' for key 'name'
mysql> insert into user5 values(1,'lisi');
Query OK, 1 row affected (0.17 sec)
mysql> select * from user5;
+------+----------+
| id | name |
+------+----------+
| 1 | zhangsan |
| 1 | lisi |
+------+----------+
2 rows in set (0.00 sec)
这里就有一个疑惑,这不和我们前面学的主键约束很像吗?
简单来说,就是主键约束不允许为空,而唯一约束可以为空,他们俩的相同之处就是都不可以重复。
mysql> insert into user5 values(NULL,'NULL');
Query OK, 1 row affected (0.68 sec)
mysql> select * from user5;
+------+----------+
| id | name |
+------+----------+
| 1 | zhangsan |
| 1 | lisi |
| NULL | wanger |
| NULL | NULL |
+------+----------+
4 rows in set (0.00 sec)
上面显示,唯一约束可以为空(NULL)而上面的主键约束就不可以为空,
这里注意
mysql> insert into user5 values(1,'NULL');
ERROR 1062 (23000): Duplicate entry 'NULL' for key 'name'
注意这里我把NULL写成’NULL’,当成了字符,所以会导致重复报错。唯一键是可以存在多个null的,因为根据NULL的定义,NULL表示的是未知,因此两个NULL比较的结果既不相等,也不不等,结果仍然是未知。根据这个定义,多个NULL值的存在应该不违反唯一约束,所以是合理的。
总结:
1.建表的时候添加约束
2.可以使用alter…add…方式添加约束
3.使用alter…modif…
4.删除约束alter…drop…
6.非空约束
保证修饰的字段不能为空,NULL 。在建表的时候加上not null
mysql> create table user9(
-> id int,
-> name varchar(20) not null #加上了not null
-> );
Query OK, 0 rows affected (0.89 sec)
mysql> desc user9;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(20) | NO | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> insert into user9 (id) values(1);
ERROR 1364 (HY000): Field 'name' doesn't have a default value
# 报错,因为名字没传值是不允许的
mysql> insert into user9 (id) values('lisi');
# 没传id,只传name是可以的,这样的话,id是默认的NULL
可以看到在Null,那一列name上面是NO
7. 默认约束
就是当我们插入字段值的时候,如果没有传值,就会使用默认值。
CREATE TABLE user2 (
id INT,
name VARCHAR(20),
age INT DEFAULT 10
);
代码实验:
mysql> create table user10(
-> id int,
-> name varchar(20),
-> age int default 10 #default后面加上默认值
-> );
Query OK, 0 rows affected (1.15 sec)
mysql> desc user10;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(20) | YES | | NULL | |
| age | int(11) | YES | | 10 | |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> insert into user10 (id,name) values(1,'zhangsan');
#并没有给age传值,如果写了age就按照写的值为准
Query OK, 1 row affected (0.55 sec)
mysql> select * from user10;
+------+----------+------+
| id | name | age |
+------+----------+------+
| 1 | zhangsan | 10 |
+------+----------+------+
1 row in set (0.00 sec)
8. 外键约束
涉及到两个表:主表和副表(也可以说是父表和子表),一个表引用另一个表。
下面我们建两个表:
班级表
mysql> create table classes(
-> id int primary key,
-> name varchar(20)
-> );
Query OK, 0 rows affected (0.88 sec)
学生表
mysql> create table students(
-> id int primary key,
-> name varchar(20),
-> class_id int,
-> foreign key(class_id) references classes(id)
-> );
Query OK, 0 rows affected (1.20 sec)
学生表中的 class_id 的值必须来自 classs 表中的 id 字段,且定义的时候就要确定类型相同。
- 主表中没有的数据值,在副表中是不可以使用的。
- 当主表中的记录被副表引用时,主表中被引用的值是不可以被删除的。
现在向班级表中插入数据:
mysql> insert into classes values(1, '一班');
Query OK, 1 row affected (0.64 sec)
mysql> insert into classes values(2, '二班');
Query OK, 1 row affected (0.15 sec)
mysql> insert into classes values(3, '三班');
Query OK, 1 row affected (0.15 sec)
mysql> select * from classes;
+----+--------+
| id | name |
+----+--------+
| 1 | 一班 |
| 2 | 二班 |
| 3 | 三班 |
+----+--------+
3 rows in set (0.00 sec)
再向学生表添加数据:
mysql> insert into students values(181,'张三',1);
Query OK, 1 row affected (0.64 sec)
mysql> insert into students values(182,'张三',2);
Query OK, 1 row affected (0.08 sec)
mysql> insert into students values(183,'张三',3);
Query OK, 1 row affected (0.18 sec)
mysql> insert into students values(185,'李三',5);
# 报错
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constaaint fails
# 主表(父表)classes 中没有的数据值,在副表(子表)students 中,是不可以使用的;
mysql> delete from classes where id=3;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`test`.`students`, CONSTRAINT `students_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `classes` (`id`))
# 主表中的记录被副表引用时,主表不可以被删除。
mysql> select * from students;
+-----+--------+----------+
| id | name | class_id |
+-----+--------+----------+
| 181 | 张三 | 1 |
| 182 | 张三 | 2 |
| 183 | 张三 | 3 |
+-----+--------+----------+
3 rows in set (0.00 sec)
三. 数据库的 三大设计范式
1. 第一范式:数据中所有字段都是不可分割的原子值
# 创建一个表
mysql> create table student2(
-> id int primary key,
-> name varchar(20),
-> address varchar(20),
-> );
# 向表里面插入数据
insert into student2 values(1,'张三','中国四川省成都市武侯区武侯大道100号')
insert into student2 values(2,'李四','中国四川省成都市武侯区京城大道200号')
insert into student2 values(3,'王五','中国四川省成都市高新区天赋大道90号')
其中的地址,其实还是可以拆分的可以再分成省份、城市、区,上图就是可拆分,不满足第一范式。我们要把表拆的详细一点,后期方便统计。
mysql> create table student2(
-> id int primary key,
-> name varchar(20),
-> cuntry varchar(30),
-> privence varchar(30),
-> city varchar(30),
-> details varchar(30),
-> );
# 经过这样的修改满足第一范式了
- 只要字段值还可以继续拆分,就不满足第一范式。
- 范式设计得越详细,对某些实际操作可能会更好,但并非都有好处,需要对项目的实际情况进行设定。
2. 第二范式
在满足第一范式的前提下,其他列都必须完全依赖于主键列。
如果出现不完全依赖,只可能发生在联合主键的情况下:
下面我们创建一个表,用来当做订单:
mysql> create table myorser(
-> product_id int, #产品号
-> customer_id int, #用户号
-> product_name varchar(20),
-> customer_name varchar(20),
-> primary key(product_id,customer_id) #产品号和用户号形成联合主键
-> );
Query OK, 0 rows affected (1.21 sec)
这里就发现一个问题,除主键外其他列,只依赖于主键的部分字段。
产品的名字只和产品号有关、用户的名字只和用户号有关,就是不完全依赖于主键,不满足第二范式!!
解决方法如下,拆表:
mysql> create table myorder2( #订单id表
-> order_id int primary key,
-> product_id int,
-> customer_id int
-> );
Query OK, 0 rows affected (0.99 sec)
mysql> create table product( #产品名 表,依赖于产品id
-> id int primary key,
-> name varchar(20)
-> );
Query OK, 0 rows affected (0.93 sec)
mysql> create table customer( #顾客名 表,依赖于顾客id
-> id int primary key,
-> name varchar(20)
-> );
Query OK, 0 rows affected (0.82 sec)
将表拆分成三个表之后就满足了第二范式的设计。
3. 第三范式
必须满足第二范式,除主键列的其他列之间不能有传递依赖关系
mysql> create table myorder2(
-> order_id int primary key,
-> product_id int,
-> customer_id int,
-> customer_phone varchar(20)
-> );
Query OK, 0 rows affected (0.99 sec)
这里相比上面订单id表,多了一个顾客手机,很明显customer_phone和order_id主键有关系,但是customer_phone还依赖于customer_id(除主键外的其他键)。这就不满足第三范式了,应该将 顾客的手机 放入顾客表中才满足第三范式。
mysql> create table customer( #顾客名 表,依赖于顾客id
-> id int primary key,
-> name varchar(20),
-> phone varchar(15)
-> );
这样才满足第三范式。