3.1表的存储方式

  • 存储方式一: MyISAM 5.5及以下默认存储方式
  • 存储文件个数:表结构表中的数据,索引
  • 适合做读,插入数据比较频繁的,对修改和删除涉及较少,索引和数据分开存储
  • 支持表级锁
  • 不支持行级锁 不支持事务 不支持外键
  • 存储方式二: innoDB 5.6及以上默认存储方式
  • 存储文件个数 : 表结构,表中的数据
  • 适合并发较高,对事物一致性要求较高,行队更适应频繁的删除和修改操作,索引和数据存在一起
  • 支持行级锁和表级锁
  • 支持事务
  • 支持外键
  • 存储方式三: MEMORY内存
  • 存储文件个数:表结构
  • 优势 : 增删改查都很快(用于热点新闻)
  • 数据存在内存中,表结构存在硬盘上,查询速度快
  • 劣势 : 重启数据消失,容量有限

3.2表的创建

表就相当于文件,表中的一条记录就相当于文件的一行内容,不同的是,表中的一条记录有对应的标题,称为表的字段

mysql 插入表 始终插入到第一排_mysql 插入表 始终插入到第一排

3.2.1建表语句

#语法:
mysql>create table 表名(
    字段名1 类型[(宽度) 约束条件],
    字段名2 类型[(宽度) 约束条件],
    字段名3 类型[(宽度) 约束条件],
);
#注意:
1. 在同一张表中,字段名是不能相同
2. 宽度和约束条件可选
3. 字段名和类型是必须的
  • 例一: mysql>create table t1 (id int,name char(4));
  • 例二: mysql>create table t3 (id int,name char(4)) engine=myisam;

3.2.2.查看表结构

  • mysql>desc 表名 查看表字段的基础信息
  • mysql>describe 表名;
  • mysql>show create table 表名; 能够看到和这张表相关的所有信息
  • mysql>show create table 表名 \G 能显示较为整洁
  • mysql>show create table 表名 \G; 能显示较为整洁(加分号会报错)

mysql 插入表 始终插入到第一排_mysql_02

  • 使用分号或者\G

mysql 插入表 始终插入到第一排_存储方式_03

mysql 插入表 始终插入到第一排_数据_04

mysql 插入表 始终插入到第一排_存储方式_05

证明使用memory存储退出数据库后登录会清空.

3.3字段的数据类型

3.3.1数值类型

MySQL支持所有标准SQL数值数据类型。这些类型包括严格数值数据类型(INTEGER、SMALLINT、DECIMAL和NUMERIC),以及近似数值数据类型(FLOAT、REAL和DOUBLE PRECISION)。关键字INT是INTEGER的同义词,关键字DEC是DECIMAL的同义词。MySQL支持的整数类型有TINYINT、MEDIUMINT和BIGINT。下面的表显示了需要的每个整数类型的存储和范围。

对于小数的表示,MYSQL分为两种方式:浮点数和定点数。浮点数包括float(单精度)和double(双精度),而定点数只有decimal一种,在mysql中以字符串的形式存放,比浮点数更精确,适合用来表示货币等精度高的数据。BIT数据类型保存位字段值,并且支持MyISAM、MEMORY、InnoDB和BDB表。

mysql 插入表 始终插入到第一排_mysql_06

mysql 插入表 始终插入到第一排_mysql_07

1.整数

mysql 插入表 始终插入到第一排_mysql_08

mysql 插入表 始终插入到第一排_mysql 插入表 始终插入到第一排_09

  • 总结
  • int默认是有符号的
  • 它能表示的数字范围不被宽度约束
  • 他只能约束数字的显示宽度
#默认创建(有符号)
mysql>create table t4 (id1 int,id2 int);
#创建一个无符号的int数据
mysql>create table t5 (id1 int unsigned,id2 int);

2.小数

mysql 插入表 始终插入到第一排_存储方式_10

mysql 插入表 始终插入到第一排_存储方式_11

# create table t6 (f1 float(5,2),d1 double(5,2));   会四舍五入
# create table t7 (f1 float,d1 double);


create table t8 (d1 decimal,d2 decimal(25,20));   
#非常准确,能表示小数点后30位,后面不指定位数时默认保留整数

mysql 插入表 始终插入到第一排_mysql 插入表 始终插入到第一排_12

3.3.2时间类型

mysql 插入表 始终插入到第一排_mysql_13

1.date / time / datetime

mysql> create table t4 (d date,t time,dt datetime);
Query OK, 0 rows affected (0.02 sec)

mysql> desc t4;
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| d     | date     | YES  |     | NULL    |       |
| t     | time     | YES  |     | NULL    |       |
| dt    | datetime | YES  |     | NULL    |       |
+-------+----------+------+-----+---------+-------+
3 rows in set (0.01 sec)

mysql> insert into t4 values (now(),now(),now());
Query OK, 1 row affected, 1 warning (0.01 sec)

mysql> select * from t4;
+------------+----------+---------------------+
| d          | t        | dt                  |
+------------+----------+---------------------+
| 2018-09-21 | 14:51:51 | 2018-09-21 14:51:51 |
+------------+----------+---------------------+
1 row in set (0.00 sec)

mysql> insert into t4 values (null,null,null);
Query OK, 1 row affected (0.01 sec)

mysql> select * from t4;
+------------+----------+---------------------+
| d          | t        | dt                  |
+------------+----------+---------------------+
| 2018-09-21 | 14:51:51 | 2018-09-21 14:51:51 |
| NULL       | NULL     | NULL                |
+------------+----------+---------------------+
2 rows in set (0.00 sec)

2.timestemp

#示例一:
mysql> create table t5 (id1 timestamp);
Query OK, 0 rows affected (0.02 sec)

mysql> desc t5;
+-------+-----------+------+-----+-------------------+-----------------------------+
| Field | Type      | Null | Key | Default           | Extra                       |
+-------+-----------+------+-----+-------------------+-----------------------------+
| id1   | timestamp | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-------+-----------+------+-----+-------------------+-----------------------------+
1 row in set (0.00 sec)

# 插入数据null,会自动插入当前时间的时间
mysql> insert into t5 values (null);
Query OK, 1 row affected (0.00 sec)

mysql> select * from t5;
+---------------------+
| id1                 |
+---------------------+
| 2018-09-21 14:56:50 |
+---------------------+
1 row in set (0.00 sec)

#添加一列 默认值是'0000-00-00 00:00:00'
mysql> alter table t5 add id2 timestamp;
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> show create table t5 \G;
*************************** 1. row ***************************
       Table: t5
Create Table: CREATE TABLE `t5` (
  `id1` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `id2` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

ERROR: 
No query specified

# 手动修改新的列默认值为当前时间
mysql> alter table t5 modify id2 timestamp default current_timestamp;
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> show create table t5 \G;
*************************** 1. row ***************************
       Table: t5
Create Table: CREATE TABLE `t5` (
  `id1` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `id2` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

ERROR: 
No query specified

mysql> insert into t5 values (null,null);
Query OK, 1 row affected (0.01 sec)

mysql> select * from t5;
+---------------------+---------------------+
| id1                 | id2                 |
+---------------------+---------------------+
| 2018-09-21 14:56:50 | 0000-00-00 00:00:00 |
| 2018-09-21 14:59:31 | 2018-09-21 14:59:31 |
+---------------------+---------------------+
2 rows in set (0.00 sec)
#示例二
mysql> create table t6 (t1 timestamp);
Query OK, 0 rows affected (0.02 sec)

mysql> desc t6;
+-------+-----------+------+-----+-------------------+-----------------------------+
| Field | Type      | Null | Key | Default           | Extra                       |
+-------+-----------+------+-----+-------------------+-----------------------------+
| t1    | timestamp | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-------+-----------+------+-----+-------------------+-----------------------------+
1 row in set (0.01 sec)

mysql> insert into t6 values (19700101080001);
Query OK, 1 row affected (0.00 sec)

mysql> select * from t6;
+---------------------+
| t1                  |
+---------------------+
| 1970-01-01 08:00:01 |
+---------------------+
1 row in set (0.00 sec)
# timestamp时间的下限是19700101080001
mysql> insert into t6 values (19700101080000);
ERROR 1292 (22007): Incorrect datetime value: '19700101080000' for column 't1' at row 1

mysql> insert into t6 values ('2038-01-19 11:14:07');
Query OK, 1 row affected (0.00 sec)
# timestamp时间的上限是2038-01-19 11:14:07
mysql> insert into t6 values ('2038-01-19 11:14:08');
ERROR 1292 (22007): Incorrect datetime value: '2038-01-19 11:14:08' for column 't1' at row 1
mysql>

3.year

mysql> create table t7 (y year);
Query OK, 0 rows affected (0.02 sec)

mysql> insert into t7 values (2018);
Query OK, 1 row affected (0.00 sec)

mysql> select * from t7;
+------+
| y    |
+------+
| 2018 |
+------+
1 row in set (0.00 sec)

4.时间的写入

写入当前时间

mysql> create table tt1(y year,d date,dt datetime,ts timestamp);
Query OK, 0 rows affected (0.96 sec)

mysql> insert into tt1 values(now(),now(),now(),now());
Query OK, 1 row affected, 1 warning (0.21 sec)

mysql> select * from tt1;
+------+------------+---------------------+---------------------+
| y    | d          | dt                  | ts                  |
+------+------------+---------------------+---------------------+
| 2019 | 2019-09-28 | 2019-09-28 16:48:49 | 2019-09-28 16:48:49 |
+------+------------+---------------------+---------------------+
1 row in set (0.00 sec)

mysql> insert into tt1 (y) values (2018);
Query OK, 1 row affected (0.14 sec)

mysql> select * from tt1;
+------+------------+---------------------+---------------------+
| y    | d          | dt                  | ts                  |
+------+------------+---------------------+---------------------+
| 2019 | 2019-09-28 | 2019-09-28 16:48:49 | 2019-09-28 16:48:49 |
| 2018 | NULL       | NULL                | 2019-09-28 16:50:38 |
+------+------------+---------------------+---------------------+
2 rows in set (0.00 sec)

mysql> show create table tt1;
+-------+----------------------------------------------------------------------------------
| Table | Create Table
--------------------------------------------------------+
| tt1   | CREATE TABLE `tt1` (
  `y` year(4) DEFAULT NULL,
  `d` date DEFAULT NULL,
  `dt` datetime DEFAULT NULL,
  `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-------+----------------------------------------------------------------------------------
create table t9(
    y year,d date,
    dt datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
    ts timestamp
);

写入任意时间

#数字型写入
mysql> insert into tt1 values(2019,20180701,20170701121212,20160102030405);
Query OK, 1 row affected (0.10 sec)

#字符串型写入
mysql> insert into tt1 values(2019,20180701,'2017-07-01 12:12:12','2016-01-02 03:04:05');
Query OK, 1 row affected (0.11 sec)

mysql> select * from tt1;
+------+------------+---------------------+---------------------+
| y    | d          | dt                  | ts                  |
+------+------------+---------------------+---------------------+
| 2019 | 2018-07-01 | 2017-07-01 12:12:12 | 2016-01-02 03:04:05 |
| 2019 | 2018-07-01 | 2017-07-01 12:12:12 | 2016-01-02 03:04:05 |
+------+------------+---------------------+---------------------+
2 rows in set (0.00 sec)

另外这种方式也可以写入:

mysql 插入表 始终插入到第一排_mysql_14

3.3.3字符串类型

mysql 插入表 始终插入到第一排_mysql 插入表 始终插入到第一排_15

  • char 定长的单位
  • 存储时 :alex -----> alex ,
  • varchar 变长的单位
  • 存储时:alex ------> alex4
  • 哪一种存储方式好?
  • vachar :节省空间,存储效率相对低
  • char :浪费空间,存储效率相对高,长度变化小的
#手机号码,身份证号,用户名,密码   char  *****
#评论,微博,说说,微信状态        varchar

create table t11 (name1 char(5),name2 varchar(5));

mysql 插入表 始终插入到第一排_数据_16

3.3.4ENUM和SET类型

#ENUM  枚举
#set   多选,自动去重

create table tt2(
name char(12),
gender ENUM('male','female'),
hobby set('抽烟','喝酒','烫头','洗脚')    
);

mysql 插入表 始终插入到第一排_存储方式_17

3.3.5对象

blob   二进制大对象(存储图片,视频等媒体流信息)
clob   字符大对象(存储较大文本)

3.4约束

3.4.1 unsigned

  • 设置某一个数字无符号

3.4.2 not null

  • 某一个字段不能为空
create table t1(
    id int not null,
    name char(12) not null,
    age int
);

   

mysql 插入表 始终插入到第一排_数据_18

  • not null 不生效
#not null不生效:
    不支持对not null字段插入null值
    不支持对自增长字段插入"”值
    不支持text字段有默认值

#直接在mysql中生效(重启失效):
mysql>set sql_mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION";

#配置文件添加(永久失效):
sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
设置严格模式:
    不支持对not null字段插入null值
    不支持对自增长字段插入”值
    不支持text字段有默认值

3.4.3default

  • 给某个字段设置默认值
  • 我们约束某一列不为空,如果这一列中经常有重复的内容,就需要我们频繁的插入,这样会给我们的操作带来新的负担,于是就出现了默认值的概念。
  • 默认值,创建列时可以指定默认值,当插入数据时如果未主动设置,则自动添加默认值
#创建表
create table t2(
    id int not null,
    name char(12) not null,
    age int not null,
    gender enum('male','female') not null default 'male'
);

#插入数据
insert into t2(id,name,age) values(1,'张三','20');

mysql 插入表 始终插入到第一排_mysql 插入表 始终插入到第一排_19

3.4.4 unique

  • 设置某一个字段不能重复
#创建表
create table t3(
 id int unique,
 username char(12) unique,
 password char(18)
);

#插入数据
insert into t3 values(1,'张三','12345');

mysql 插入表 始终插入到第一排_存储方式_20

mysql 插入表 始终插入到第一排_mysql 插入表 始终插入到第一排_21

联合唯一

#创建表
create table t4(
 id int,
 ip char(15),
 server char(10),
 port int,
 unique(ip,port)
);

#插入数据
insert into t4 values(1,"192.168.12.11","mysql",3306);

mysql 插入表 始终插入到第一排_数据_22

3.4.5 auto_increment

  • 设置某一个int类型的字段,自动增加
  • 前提 :自增字段必须是 数字 且 必须唯一 ,自带非空属性
#
创建表
create table t5(
    id int unique auto_increment,
    name char(12)
);

#插入数据
insert into t5 values(1,'张三');

mysql 插入表 始终插入到第一排_mysql_23

mysql 插入表 始终插入到第一排_mysql 插入表 始终插入到第一排_24

3.4.6 primary

  • 主键 :约束这个字段 非空(not null)且唯一(unique),的字段,你指定的第一个非空且唯一自动定义为主键
  • 一张表只能设置一个主键且最好设置一个主键

单字段主键

#方法一:not null+unique
create table department1(
    id int not null unique, #主键
    name varchar(20) not null unique,
    comment varchar(100)
);

mysql> desc department1;
+---------+--------------+------+-----+---------+-------+
| Field   | Type         | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+-------+
| id      | int(11)      | NO   | PRI | NULL    |       |
| name    | varchar(20)  | NO   | UNI | NULL    |       |
| comment | varchar(100) | YES  |     | NULL    |       |
+---------+--------------+------+-----+---------+-------+
rows in set (0.01 sec)

#方法二:在某一个字段后用primary key
create table department2(
    id int primary key, #主键
    name varchar(20),
    comment varchar(100)
);

mysql> desc department2;
+---------+--------------+------+-----+---------+-------+
| Field   | Type         | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+-------+
| id      | int(11)      | NO   | PRI | NULL    |       |
| name    | varchar(20)  | YES  |     | NULL    |       |
| comment | varchar(100) | YES  |     | NULL    |       |
+---------+--------------+------+-----+---------+-------+
rows in set (0.00 sec)

#方法三:在所有字段后单独定义primary key
create table department3(
    id int,
    name varchar(20),
    comment varchar(100),
    primary key(id) #创建主键并为其命名pk_name
);

mysql> desc department3;
+---------+--------------+------+-----+---------+-------+
| Field   | Type         | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+-------+
| id      | int(11)      | NO   | PRI | NULL    |       |
| name    | varchar(20)  | YES  |     | NULL    |       |
| comment | varchar(100) | YES  |     | NULL    |       |
+---------+--------------+------+-----+---------+-------+
rows in set (0.01 sec)

# 方法四:给已经建成的表添加主键约束
mysql> create table department4(
    -> id int,
    -> name varchar(20),
    -> comment varchar(100));
Query OK, 0 rows affected (0.01 sec)

mysql> desc department4;
+---------+--------------+------+-----+---------+-------+
| Field   | Type         | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+-------+
| id      | int(11)      | YES  |     | NULL    |       |
| name    | varchar(20)  | YES  |     | NULL    |       |
| comment | varchar(100) | YES  |     | NULL    |       |
+---------+--------------+------+-----+---------+-------+
3 rows in set (0.01 sec)

mysql> alter table department4 modify id int primary key;
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc department4;
+---------+--------------+------+-----+---------+-------+
| Field   | Type         | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+-------+
| id      | int(11)      | NO   | PRI | NULL    |       |
| name    | varchar(20)  | YES  |     | NULL    |       |
| comment | varchar(100) | YES  |     | NULL    |       |
+---------+--------------+------+-----+---------+-------+
3 rows in set (0.01 sec)

多字段主键

create table service(
    ip varchar(15),
    port char(5),
    service_name varchar(10) not null,
    primary key(ip,port)
);


mysql> desc service;
+--------------+-------------+------+-----+---------+-------+
| Field        | Type        | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+-------+
| ip           | varchar(15) | NO   | PRI | NULL    |       |
| port         | char(5)     | NO   | PRI | NULL    |       |
| service_name | varchar(10) | NO   |     | NULL    |       |
+--------------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

mysql> insert into service values
    -> ('172.16.45.10','3306','mysqld'),
    -> ('172.16.45.11','3306','mariadb')
    -> ;
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> insert into service values ('172.16.45.10','3306','nginx');
ERROR 1062 (23000): Duplicate entry '172.16.45.10-3306' for key 'PRIMARY'

联合主键(不常用)

mysql 插入表 始终插入到第一排_mysql_25

3.4.7foreign key

#创建表

#部门表
create table post(
    pid int primary key,
    postname char(10) not null unique,
    comment varchar(255),
    phone_num char(11)
);   

#员工表
create table staff(
    id int primary key auto_increment,
    age int,
    gender enum('male','female'),
    salary float(8,2),
    hire_date date,
    post_id int,
    foreign key(post_id) references post(pid)
);
#注:外键关联的那张表的字段必须为unique

#插入数据
insert into post values(1,'java部','一个专职于java的部门','1234567');
insert into staff values(1,20,'male',10000,'20181201030405',1);

mysql 插入表 始终插入到第一排_存储方式_26

  • cascade方式 :在父表上update/delete记录时,同步update/delete掉子表的匹配记录
  • set null方式 :在父表上update/delete记录时,将子表上匹配记录的列设为null,要注意子表的外键列不能为not null
  • Set default方式 :父表有变更时,子表将外键列设置成一个默认的值 但Innodb不能识别
create table staff2(
    id  int primary key auto_increment,
    age int,
    gender  enum('male','female'),
    salary  float(8,2),
    hire_date date,
    post_id int,
    foreign key(post_id) references post(pid) on update cascade on delete set null
);

mysql 插入表 始终插入到第一排_mysql 插入表 始终插入到第一排_27

3.5 表结构的修改

  • 修改表名
  • alter table 表名 rename 新表名;
  • 增加字段
  • alter table 表名 add 字段名 数据类型 [完整性约束条件];
  • 删除字段
  • alter table 表名 drop 字段名;
  • 修改字段
  • alter table 表名 modify 字段名 数据类型 [完整性的约束条件];
    修改已经存在的字段的类型,宽度和约束
  • alter table 表名 change 旧字段名 新字段名 旧数据类型 [完整性约束条件…];
    修改已经存在的字段的类型,宽度,约束 及字段名字
  • 修改字段排列顺序/在增加的时候指定字段位置
    例 : 原字段顺序 id name age
  • alter table 表名 modify age int not null after id
    将age 字段放在name字段之前
  • alter table 表名 modify age int not null first

3.6 表与表之间的关系

3.6.1一对多

  • foreign key 永远是在多的那张表中设置外键
  • 多个学生都是一个班级的
  • 学生表 关联 班级表
  • 学生是多 ,班级是一

3.6.2一对一

  • foreign key +unique 后出现的的那张表中的数据作为外键(并且约束这个外键唯一)
  • 客户关系表 :手机号码,招生老师,上次联系时间,备注信息
  • 学生表 :姓名,入学日期,缴费日期,结业时间

3.6.3多对多

  • 产生第三张表,把两个关联关系的字段作为第三张表的外键
  • 作者
     
  • mysql 插入表 始终插入到第一排_mysql 插入表 始终插入到第一排_28