表操作

  1. MySQL中的存储引擎

    ​ MySQL中的数据用各种不同的技术(方式)存储在文件(或者内存)中。这些技术中的每一种技术都使用不同的存储机制、索引技巧、锁定水平并且最终提供广泛的不同的功能和能力。通过选择不同的技术,你能够获得额外的速度或者功能,从而改善你的应用的整体功能。

    ​ 这些不同的技术以及配套的相关功能(数据的存储方式)在MySQL中被称作存储引擎(也称作表类型)。 可通过show engines查看存储引擎。

    • MySQL中常用存储引擎

      • innodb

        是MySQL 5.6以上版本默认的存储方式,将数据分为两个文件存储,一个是表结构 ,一个是树形结构+数据。具有以下特点:

        row-level locking 行级锁

        table-level locking 表级锁

        foreign keys 外键约束

        树tree - 加速查询(树形结构(数据+树)+表结构)

        transaction 事务,是保证数据的安全,数据的完整性而设置的概念

        并发 修改 删除操作的效率比较高

        持久化存储

      • myisam

        MySQL 5.5以下版本的默认存储方式,将数据分为三个文件存储,一个是表结构 ,一个是树形结构,另一个是数据。具有以下特征:

        table-level locking 表级锁

        读 插入操作的效率高一些

        持久化存储

        树tree - 加速查询(树形结构+数据+表结构)

        create table myisam_t (id int,name char(18)) engine=myisam
      • memory

        基于hash,将所有的数据保存在内存中,可提供极快的访问。缺点是对表的大小有限制,一旦数据库关闭数据就会丢失。

        create table memory_t (id int,name char(18) engine=memory)
    • 存储引擎相关sql语句

      查看当前的默认存储引擎:

      show variables like "default_storage_engine";

      查询当前数据库支持的存储引擎:

      show engines \G;

      建表时的指令:

      create table ai(id bigint(12),name varchar(200)) engine=myisam;
      create table country(id int(4),cname varchar(50)) engine=innodb;

      修改一个已经存在的表的存储引擎:

      alter table ai engine = innodb;

      也可以在配置文件中指定:

      # my.ini文件
      [mysqld]
      default-storage-engine=INNODB
    • MySQL的工作流程

    • 介绍

      表就相当于文件,表中一条记录就相当于文件的一行内容。

      id,name,age,sex,phone,job称为字段,其余的,一行内容称为一条记录

    • 创建表

      # 语法
      create table 表名(
      字段名1 类型[(宽度) 约束条件],
      字段名1 类型[(宽度) 约束条件],
      字段名1 类型[(宽度) 约束条件],
      );
      #注意:
      1. 在同一张表中,字段名是不能相同
      2. 宽度和约束条件可选
      3. 字段名和类型是必须的
    • 查看表结构

      使用desc 表名:

      mysql> desc staff_info;
      +-------+-----------------------+------+-----+---------+-------+
      | Field | Type                  | Null | Key | Default | Extra |
      +-------+-----------------------+------+-----+---------+-------+
      | id    | int(11)               | YES  |     | NULL    |       |
      | name  | varchar(50)           | YES  |     | NULL    |       |
      | age   | int(3)                | YES  |     | NULL    |       |
      | sex   | enum('male','female') | YES  |     | NULL    |       |
      | phone | bigint(11)            | YES  |     | NULL    |       |
      | job   | varchar(11)           | YES  |     | NULL    |       |
      +-------+-----------------------+------+-----+---------+-------+

      使用show create table 表名\G;:

      mysql> show create table staff_info\G;
      *************************** 1. row ***************************Table: staff_info
      Create Table: CREATE TABLE `staff_info` (`id` int(11) DEFAULT NULL,`name` varchar(50) DEFAULT NULL,`age` int(3) DEFAULT NULL,`sex` enum('male','female') DEFAULT NULL,`phone` bigint(11) DEFAULT NULL,`job` varchar(11) DEFAULT NULL
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8
      1 row in set (0.01 sec)
    • 数据类型

      1. 数值类型

        MySQL支持所有标准的sql数值数据类型。

        类型 大小 范围(有符号) 范围(无符号)unsigned约束 用途
        TINYINT 1 字节 (-128,127) (0,255) 小整数值
        SMALLINT 2 字节 (-32 768,32 767) (0,65 535) 大整数值
        MEDIUMINT 3 字节 (-8 388 608,8 388 607) (0,16 777 215) 大整数值
        INT或INTEGER 4 字节 (-2 147 483 648,2 147 483 647) (0,4 294 967 295) 大整数值
        BIGINT 8 字节 (-9 233 372 036 854 775 808,9 223 372 036 854 775 807) (0,18 446 744 073 709 551 615) 极大整数值
        FLOAT 4 字节float(255,30) (-3.402 823 466 E+38,-1.175 494 351 E-38),0,(1.175 494 351 E-38,3.402 823 466 351 E+38) 0,(1.175 494 351 E-38,3.402 823 466 E+38) 单精度 浮点数值
        DOUBLE 8 字节double(255,30) (-1.797 693 134 862 315 7 E+308,-2.225 073 858 507 201 4 E-308),0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) 0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) 双精度 浮点数值
        DECIMAL 对DECIMAL(M,D) ,如果M>D,为M+2否则为D+2double(65,30) 依赖于M和D的值 依赖于M和D的值 小数值

        其中最常用的是tinyint、int、float。

        # 创建一个表,默认宽度的tinyint、默认宽度的int、无符号的tingyint、无符号的int
        mysql> create table int_t1(-> ti tinyint,-> i int,-> tiun tinyint unsigned,-> iun int unsigned-> );
        Query OK, 0 rows affected (0.70 sec)# 插入超过长度的数值,并不会报错,写入的是能写入的最大值
        mysql> insert into int_t1 values(123456789,123456789,123456789,123456789);
        Query OK, 1 row affected, 2 warnings (0.48 sec)mysql> select * from int_t1;
        +------+-----------+------+-----------+
        | ti   | i         | tiun | iun       |
        +------+-----------+------+-----------+
        |  127 | 123456789 |  255 | 123456789 |
        +------+-----------+------+-----------+
        1 row in set (0.00 sec)# 插入复数也不会报错,无符号的项并不能被写入
        mysql> insert into int_t1 values(-123456789,-123456789,-123456789,-123456789);
        Query OK, 1 row affected, 3 warnings (0.03 sec)mysql> select * from int_t1;
        +------+------------+------+-----------+
        | ti   | i          | tiun | iun       |
        +------+------------+------+-----------+
        |  127 |  123456789 |  255 | 123456789 |
        | -128 | -123456789 |    0 |         0 |
        +------+------------+------+-----------+
        2 rows in set (0.00 sec)
        # 创建一个默认长度的float和double以及限制长度的float和double
        mysql> create table fd_t1(-> f float,-> d double,-> f2 float(5,2),-> d2 double(5,2)-> );
        Query OK, 0 rows affected (0.83 sec)# 插入超过限制长度的数,发现限制长度的float和double都会对余下的数进行四舍五入
        mysql> insert into fd_t1 values(123.45678,123.45678,123.45678,123.45678);
        Query OK, 1 row affected (0.48 sec)mysql> select * from fd_t1;
        +---------+-------------------+--------+--------+
        | f       | d                 | f2     | d2     |
        +---------+-------------------+--------+--------+
        | 123.457 |         123.45678 | 123.46 | 123.46 |
        +---------+-------------------+--------+--------+
        2 rows in set (0.00 sec)
        
        # 创建一个默认长度的decimal和限制小数位为20位的decimal
        mysql> create table dec_t1(-> dec1 decimal,-> dec2 decimal(30,20)-> );
        Query OK, 0 rows affected (0.78 sec)# 插入数字发现decimal默认小数位为零,限制小数位为20后插入数字若不足则会进行补全
        mysql> insert into dec_t1 values(123.12345678912345,123.12345678912345);
        Query OK, 1 row affected, 1 warning (0.48 sec)mysql> select * from dec_t1;
        +------+--------------------------+
        | dec1 | dec2                     |
        +------+--------------------------+
        |  123 | 123.12345678912345000000 |
        +------+--------------------------+
        1 row in set (0.00 sec)

        修改字段类型:

        alter table 表名 modify 条件 新类型
      2. 日期和时间类型

        MySQL中表示日期和时间的类型有datetime、date、timestamp、time和year。

        每个时间类型有一个有效范围和一个“零”值,当指定不合法的MySQL不能表示的值时使用“零”值。

        类型 大小 (字节) 范围 格式 用途
        DATE 3 1000-01-01/9999-12-31 YYYY-MM-DD 年月日
        TIME 3 '-838:59:59'/'838:59:59' HH:MM:SS 时分秒
        YEAR 1 1901/2155 YYYY 年份值
        DATETIME 8 1000-01-01 00:00:00/9999-12-31 23:59:59 YYYY-MM-DD HH:MM:SS 年月日时分秒
        TIMESTAMP 4 1970-01-01 00:00:00/2038结束时间是第 2147483647 秒,北京时间 2038-1-19 11:14:07,格林尼治时间 2038年1月19日 凌晨 03:14:07 YYYYMMDD HHMMSS 混合日期和时间值,时间戳
        # 创建一个含有date(日期)、time(时间)、datetime(年月日时间)的表
        mysql> create table t4(d date,t time,dt datetime);
        Query OK, 0 rows affected (0.44 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)# 通过now()函数插入当前时间
        mysql> insert into t4 values(now(),now(),now());
        Query OK, 1 row affected, 1 warning (0.16 sec)mysql> select * from t4;
        +------------+----------+---------------------+
        | d          | t        | dt                  |
        +------------+----------+---------------------+
        | 2019-07-30 | 16:37:58 | 2019-07-30 16:37:58 |
        +------------+----------+---------------------+
        1 row in set (0.00 sec)

        timestamp:

        # 创建一个含有timestamp(时间戳)的表
        mysql> create table t2 (ts timestamp);
        Query OK, 0 rows affected (0.44 sec)
        # 可以看到默认值是current_timestamp
        mysql> desc t2;
        +-------+-----------+------+-----+-------------------+-----------------------------+
        | Field | Type      | Null | Key | Default           | Extra                       |
        +-------+-----------+------+-----+-------------------+-----------------------------+
        | ts    | timestamp | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
        +-------+-----------+------+-----+-------------------+-----------------------------+
        1 row in set (0.02 sec)
        # 当插入值为空时,会自动插入当前时间的时间
        mysql> insert into t2 values(null);
        Query OK, 1 row affected (0.17 sec)mysql> select * from t2;
        +---------------------+
        | ts                  |
        +---------------------+
        | 2019-07-30 16:46:57 |
        +---------------------+
        1 row in set (0.00 sec)# 手动添加一列,默认值为'0000-00-00 00:00:00'
        mysql> alter table t2 add ts1 timestamp;
        Query OK, 0 rows affected (0.89 sec)
        Records: 0  Duplicates: 0  Warnings: 0mysql> show create table t2 \G;
        *************************** 1. row ***************************Table: t2
        Create Table: CREATE TABLE `t2` (`ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,`ts1` 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 specifiedmysql> select * from t2;
        +---------------------+---------------------+
        | ts                  | ts1                 |
        +---------------------+---------------------+
        | 2019-07-30 16:46:57 | 0000-00-00 00:00:00 |
        +---------------------+---------------------+
        1 row in set (0.00 sec)# 手动修改新的列默认值为当前时间
        mysql> alter table t2 modify ts1 timestamp default current_timestamp;
        Query OK, 0 rows affected (0.12 sec)
        Records: 0  Duplicates: 0  Warnings: 0mysql> show create table t2 \G;
        *************************** 1. row ***************************Table: t2
        Create Table: CREATE TABLE `t2` (`ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,`ts1` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8
        1 row in set (0.00 sec)ERROR:
        No query specifiedmysql> insert into t2 values(null,null);
        Query OK, 1 row affected (0.14 sec)mysql> select * from t2;
        +---------------------+---------------------+
        | ts                  | ts1                 |
        +---------------------+---------------------+
        | 2019-07-30 16:46:57 | 0000-00-00 00:00:00 |
        | 2019-07-30 17:25:56 | 2019-07-30 17:25:56 |
        +---------------------+---------------------+
        2 rows in set (0.00 sec)# timestamp时间的下限是19700101080001;上限是20380119111407
        mysql> insert into t2 values(19700101080001,'2038-01-19 11:14:07');
        Query OK, 1 row affected (0.12 sec)mysql> select * from t2;
        +---------------------+---------------------+
        | ts                  | ts1                 |
        +---------------------+---------------------+
        | 2019-07-30 16:46:57 | 0000-00-00 00:00:00 |
        | 2019-07-30 17:25:56 | 2019-07-30 17:25:56 |
        | 1970-01-01 08:00:01 | 2038-01-19 11:14:07 |
        +---------------------+---------------------+
        3 rows in set (0.02 sec)mysql> insert into t2 values(null,'2038-01-19 11:14:08');
        Query OK, 1 row affected, 1 warning (0.03 sec)mysql> select * from t2;
        +---------------------+---------------------+
        | ts                  | ts1                 |
        +---------------------+---------------------+
        | 2019-07-30 16:46:57 | 0000-00-00 00:00:00 |
        | 2019-07-30 17:25:56 | 2019-07-30 17:25:56 |
        | 1970-01-01 08:00:01 | 2038-01-19 11:14:07 |
        | 2019-07-30 17:32:30 | 0000-00-00 00:00:00 |
        +---------------------+---------------------+
        4 rows in set (0.00 sec)

        可以使datetime具有timestamp含有默认值且能自动更新的特点:

        mysql> create table t13(d date,t datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);
        Query OK, 0 rows affected (0.35 sec)mysql> insert into t13(d) values (20190416);
        Query OK, 1 row affected (0.13 sec)mysql> select * from t13;
        +------------+---------------------+
        | d          | t                   |
        +------------+---------------------+
        | 2019-04-16 | 2019-07-30 20:37:31 |
        +------------+---------------------+
        1 row in set (0.00 sec)
      3. 字符串类型

        ​ 字符串类型指CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM和SET。该节描述了这些类型如何工作以及如何在查询中使用这些类型。

        ​ 常用的有char、varchar。它们的最大长度和是否尾部空格被保留等方面也不同。在存储或检索过程中不进行大小写转换。

        ​ char列的长度固定为创建表时声明的长度,范围(0-255);而varchar的值是可变长字符串范围(0-65535)。

        ​ char:定长,速度快,占用空间大大

        ​ varchar:变长,速度慢,占用空间小

        类型 大小 用途
        CHAR 0-255字节 定长字符串
        VARCHAR 0-65535 字节 变长字符串
        TINYBLOB 0-255字节 不超过 255 个字符的二进制字符串
        TINYTEXT 0-255字节 短文本字符串
        BLOB 0-65 535字节 二进制形式的长文本数据
        TEXT 0-65 535字节 长文本数据
        MEDIUMBLOB 0-16 777 215字节 二进制形式的中等长度文本数据
        MEDIUMTEXT 0-16 777 215字节 中等长度文本数据
        LONGBLOB 0-4 294 967 295字节 二进制形式的极大文本数据
        LONGTEXT 0-4 294 967 295字节 极大文本数据
        # 创建一个表,含有限制长度为4的varchar和char
        mysql> create table t5 (v varchar(4),c char(4));
        Query OK, 0 rows affected (0.37 sec)# char数据类型会去掉末尾空格
        mysql> insert into t5 values('ab  ','ab  ');
        Query OK, 1 row affected (0.13 sec)mysql> select * from t5;
        +------+------+
        | v    | c    |
        +------+------+
        | ab   | ab   |
        +------+------+
        1 row in set (0.00 sec)
        # 对查询结果计算的长度
        mysql> select length(v),length(c) from t5;
        +-----------+-----------+
        | length(v) | length(c) |
        +-----------+-----------+
        |         4 |         2 |
        +-----------+-----------+
        1 row in set (0.11 sec)
        # 拼上一个加号会更清楚
        mysql> select concat(v,'+'),concat(c,'+') from t5;
        +---------------+---------------+
        | concat(v,'+') | concat(c,'+') |
        +---------------+---------------+
        | ab  +         | ab+           |
        +---------------+---------------+
        1 row in set (0.10 sec)# 当存储的长度超出定义的长度,会截断
        mysql> insert into t5 values('abcde','abcde');
        Query OK, 1 row affected, 2 warnings (0.13 sec)mysql> select * from t5;
        +------+------+
        | v    | c    |
        +------+------+
        | ab   | ab   |
        | abcd | abcd |
        +------+------+
        2 rows in set (0.00 sec)

        当存储类似手机号码/身份证号码以及用户名/密码这样,长度固定或有一定范围弹性的字符时使用char;当存储类似评论等范围较大时使用varchar。

      4. enum和set类型

        enum即枚举类型,它的取值范围需要在创建表时通过枚举方式显示。enum只允许从值集合中选取单个值,而不能一次取多个值。

        set类型可以允许值集合中任意选择1或多个元素进行组合。对超出范围的内容不允许写入,重复的值将进行自动去重。

        类型 大小 用途
        ENUM 对1-255个成员的枚举需要1个字节存储;对于255-65535个成员,需要2个字节存储;最多允许65535个成员。 单选:选择性别
        SET 1-8个成员的集合,占1个字节9-16个成员的集合,占2个字节17-24个成员的集合,占3个字节25-32个成员的集合,占4个字节33-64个成员的集合,占8个字节 多选:兴趣爱好
        # enum 单选
        mysql> create table t6 (name char(20),gender enum('female','male'));
        Query OK, 0 rows affected (0.32 sec)mysql> insert into t6 values('皮皮寒','male');
        Query OK, 1 row affected (0.12 sec)mysql> select * from t6;
        +-----------+--------+
        | name      | gender |
        +-----------+--------+
        | 皮皮寒    | male   |
        +-----------+--------+
        1 row in set (0.00 sec)
        # 同时插入'male,female',不会写入,不属于'male,female'的也不会写入
        mysql> insert into t6 values('皮皮寒','male,female');
        Query OK, 1 row affected, 1 warning (0.13 sec)mysql> select * from t6;
        +-----------+--------+
        | name      | gender |
        +-----------+--------+
        | 皮皮寒    | male   |
        | 皮皮寒    |        |
        +-----------+--------+
        2 rows in set (0.00 sec)
        # set 多选
        mysql> create table t7 (name char(20),hobby set('唱','跳','rap','篮球'));
        Query OK, 0 rows affected (0.35 sec)mysql> insert into t7 values('皮皮寒','唱,跳');
        Query OK, 1 row affected (0.14 sec)mysql> select * from t7;
        +-----------+---------+
        | name      | hobby   |
        +-----------+---------+
        | 皮皮寒    | 唱,跳   |
        +-----------+---------+
        1 row in set (0.00 sec)# 自带去重功能,不能选择不属于set中的项
        mysql> insert into t7 values('皮皮寒','唱,跳,唱');
        Query OK, 1 row affected (0.13 sec)mysql> select * from t7;
        +-----------+---------+
        | name      | hobby   |
        +-----------+---------+
        | 皮皮寒    | 唱,跳   |
        | 皮皮寒    | 唱,跳   |
        +-----------+---------+
        2 rows in set (0.00 sec)
    • 表的完整性约束

      ​ 为防止不符合规范的数据进入数据库,在用户对数据进行插入、修改、删除等操作时,DBMS自动按照一定的约束条件对数据进行检测,使不符合规范的数据不能进入数据库,以确保数据库中存储的数据正确、有效、相容。

      ​ 约束条件主要分为以下几类:

      ​ not null:非空约束,指定某列不能为空;

      ​ unique:唯一约束,指定某列或者几列组合不能重复

      ​ primary key:主键,指定该列的值可以唯一地标识该列记录

      ​ foreign key:外键,指定该列记录从属于主表中的一条记录,主要用于参照完整性

      1. not null

        not null 不可空

        null 可空

        # 创建一个id不能为空的表
        mysql> use day38
        Database changed
        mysql> create table t8 (id int not null);
        Query OK, 0 rows affected (0.30 sec)mysql> desc t8;
        +-------+---------+------+-----+---------+-------+
        | Field | Type    | Null | Key | Default | Extra |
        +-------+---------+------+-----+---------+-------+
        | id    | int(11) | NO   |     | NULL    |       |
        +-------+---------+------+-----+---------+-------+
        1 row in set (0.01 sec)
        # 不能向id插入空元素
        mysql> insert into t8 values(null);
        ERROR 1048 (23000): Column 'id' cannot be null
        mysql> insert into t8 values(1);
        Query OK, 1 row affected (0.15 sec)

        default:默认值,创建列时可以指定默认值,当插入数据时如果为主动设置,则自动添加默认值。

        # 创建一个含有非空id和非空默认值为222的id2的表
        mysql> create table t9 (id int not null,id2 int not null default 222);
        Query OK, 0 rows affected (0.38 sec)mysql> desc t9;
        +-------+---------+------+-----+---------+-------+
        | Field | Type    | Null | Key | Default | Extra |
        +-------+---------+------+-----+---------+-------+
        | id    | int(11) | NO   |     | NULL    |       |
        | id2   | int(11) | NO   |     | 222     |       |
        +-------+---------+------+-----+---------+-------+
        2 rows in set (0.02 sec)
        # 当更改id内容时,id2自动写入了默认值222
        mysql> insert into t9 (id) values (111);
        Query OK, 1 row affected (0.14 sec)mysql> select * from t9;
        +-----+-----+
        | id  | id2 |
        +-----+-----+
        | 111 | 222 |
        +-----+-----+
        1 row in set (0.00 sec)
        # 向id和id2填充数字,id2的默认值会被覆盖
        mysql> insert into t9 values(112,113);
        Query OK, 1 row affected (0.12 sec)mysql> select * from t9;
        +-----+-----+
        | id  | id2 |
        +-----+-----+
        | 111 | 222 |
        | 112 | 113 |
        +-----+-----+
        2 rows in set (0.00 sec)
        设置严格模式:不支持对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"
        
      2. unique

        唯一约束,指定某列或者几列组合不能重复。

        mysql> create table t10(id int,name varchar(20) unique,comment varchar(100));
        # mysql> create table t10(id int,name varchar(20),comment varchar(100),unique(name));也可以写成这样
        Query OK, 0 rows affected (0.44 sec)mysql> insert into t10 values(1,'IT','技术');
        Query OK, 1 row affected (0.03 sec)
        # 当插入相同的name时会报错
        mysql> insert into t10 values(1,'IT','技术');
        ERROR 1062 (23000): Duplicate entry 'IT' for key 'name'

        非空与unique结合:

        mysql> create table t11 (id int not null unique);
        Query OK, 0 rows affected (0.35 sec)mysql> desc t11;
        +-------+---------+------+-----+---------+-------+
        | Field | Type    | Null | Key | Default | Extra |
        +-------+---------+------+-----+---------+-------+
        | id    | int(11) | NO   | PRI | NULL    |       |
        +-------+---------+------+-----+---------+-------+
        1 row in set (0.01 sec)

        如果一个表中没有设置primary key 主键,那么第一个设置非空+唯一的字段会被设置成主键;一张表中只能有一个主键。

        # 创建一个表,其中host与port都是非空+唯一
        mysql> create table service(-> id int primary key auto_increment,#设置主键,作用=非空+唯一-> name varchar(20),-> host varchar(15) not null,-> port int not null,-> unique(host,port)    # 联合唯一,只有当这两项同时重复才会报错-> );
        Query OK, 0 rows affected (0.39 sec)mysql> insert into service values-> (1,'nginx','192.168.0.10',80),# 由于联合唯一,port单独重复也可以写入-> (2,'haproxy','192.168.0.20',80),-> (3,'mysql','192.168.0.30',3306);
        Query OK, 3 rows affected (0.07 sec)
        Records: 3  Duplicates: 0  Warnings: 0mysql> select * from service;
        +----+---------+--------------+------+
        | id | name    | host         | port |
        +----+---------+--------------+------+
        |  1 | nginx   | 192.168.0.10 |   80 |
        |  2 | haproxy | 192.168.0.20 |   80 |
        |  3 | mysql   | 192.168.0.30 | 3306 |
        +----+---------+--------------+------+
        3 rows in set (0.00 sec)
        # 当host与port同时重复时就会报错
        mysql> insert into service(name,host,port) values('nginx','192.168.0.10',80);
        ERROR 1062 (23000): Duplicate entry '192.168.0.10-80' for key 'host'
      3. primary key

        主键是为了保证表中的每一条数据的该字段都是表格中的唯一值。即它是用来独一无二的确认一个表格中的每一行数据。

        主键可以包含一个字段或多个字段。当主键包含多个栏位时,称为组合键,也可以叫联合主键。主键可以在建置新表格时设定 (运用 create table 语句),或是以改变现有的表格架构方式设定 (运用 alter table)。

        主键必须唯一,主键值非空;可以是单一字段,也可以是多字段。

        • 单字段主键

          # 方法一:not null unique
          mysql> create table t1(id int not null unique,-> name varchar(20) not null unique);
          Query OK, 0 rows affected (0.78 sec)mysql> desc t1;
          +-------+-------------+------+-----+---------+-------+
          | Field | Type        | Null | Key | Default | Extra |
          +-------+-------------+------+-----+---------+-------+
          | id    | int(11)     | NO   | PRI | NULL    |       |
          | name  | varchar(20) | NO   | UNI | NULL    |       |
          +-------+-------------+------+-----+---------+-------+
          2 rows in set (0.13 sec)
          # 方法二:在某个字段后加primary key
          mysql> create table t1(id int primary key,name varchar(20));
          Query OK, 0 rows affected (0.73 sec)mysql> desc t1;
          +-------+-------------+------+-----+---------+-------+
          | Field | Type        | Null | Key | Default | Extra |
          +-------+-------------+------+-----+---------+-------+
          | id    | int(11)     | NO   | PRI | NULL    |       |
          | name  | varchar(20) | YES  |     | NULL    |       |
          +-------+-------------+------+-----+---------+-------+
          2 rows in set (0.00 sec)
          # 方法三:在所有字段后单独定义primary key
          mysql> create table t1(id int ,name varchar(20),primary key(id));
          Query OK, 0 rows affected (0.65 sec)mysql> desc t1;
          +-------+-------------+------+-----+---------+-------+
          | Field | Type        | Null | Key | Default | Extra |
          +-------+-------------+------+-----+---------+-------+
          | id    | int(11)     | NO   | PRI | 0       |       |
          | name  | varchar(20) | YES  |     | NULL    |       |
          +-------+-------------+------+-----+---------+-------+
          2 rows in set (0.00 sec)
          # 方法四:给已经建成的表添加主键约束
          mysql> create table t1(id int,name varchar(20));
          Query OK, 0 rows affected (0.60 sec)mysql> desc t1;
          +-------+-------------+------+-----+---------+-------+
          | Field | Type        | Null | Key | Default | Extra |
          +-------+-------------+------+-----+---------+-------+
          | id    | int(11)     | YES  |     | NULL    |       |
          | name  | varchar(20) | YES  |     | NULL    |       |
          +-------+-------------+------+-----+---------+-------+
          2 rows in set (0.02 sec)mysql> alter table t1 modify id int primary key;
          Query OK, 0 rows affected (1.29 sec)
          Records: 0  Duplicates: 0  Warnings: 0mysql> desc t1;
          +-------+-------------+------+-----+---------+-------+
          | Field | Type        | Null | Key | Default | Extra |
          +-------+-------------+------+-----+---------+-------+
          | id    | int(11)     | NO   | PRI | NULL    |       |
          | name  | varchar(20) | YES  |     | NULL    |       |
          +-------+-------------+------+-----+---------+-------+
          2 rows in set (0.01 sec)
        • 多字段主键

          多个字段做主键时,表示多个字段组合在一起的内容必须唯一。

          # 当多个字段联合主键时,只有当两个字段都重复时才会报错
          mysql> create table t2(-> ip varchar(15),-> port char(5),-> service_name varchar(10) not null,-> primary key(ip,port)-> );
          Query OK, 0 rows affected (0.84 sec)mysql> desc t2;
          +--------------+-------------+------+-----+---------+-------+
          | Field        | Type        | Null | Key | Default | Extra |
          +--------------+-------------+------+-----+---------+-------+
          | ip           | varchar(15) | NO   | PRI |         |       |
          | port         | char(5)     | NO   | PRI |         |       |
          | service_name | varchar(10) | NO   |     | NULL    |       |
          +--------------+-------------+------+-----+---------+-------+
          3 rows in set (0.01 sec)mysql> insert into t2 values-> ('192.168.45.10','3306','mysql'),-> ('192.168.45.11','3306','weixin');
          Query OK, 2 rows affected (0.42 sec)
          Records: 2  Duplicates: 0  Warnings: 0mysql> insert into t2 values-> ('192.168.45.10','3306','sougou');
          ERROR 1062 (23000): Duplicate entry '192.168.45.10-3306' for key 'PRIMARY'
        • auto_increment

          约束字段为自动增长,被约束的字段必须同时被key约束

          1. 只能操作数字
          2. 自带非空属性
          3. 只能对unique字段进行设置
          4. 不受删除影响(使用truncate table t1删除,会直接从零开始)
          # 不指定id,则自动增长(也可以指定id)
          mysql> create table t3(-> id int primary key auto_increment,-> name varchar(20),-> sex enum('男','女') default '男'-> );
          Query OK, 0 rows affected (0.73 sec)mysql> desc t3;
          +-------+-------------------+------+-----+---------+----------------+
          | Field | Type              | Null | Key | Default | Extra          |
          +-------+-------------------+------+-----+---------+----------------+
          | id    | int(11)           | NO   | PRI | NULL    | auto_increment |
          | name  | varchar(20)       | YES  |     | NULL    |                |
          | sex   | enum('男','女')   | YES  |     | 男      |                |
          +-------+-------------------+------+-----+---------+----------------+
          3 rows in set (0.00 sec)mysql> insert into t3(name) values-> ('皮皮寒'),-> ('铁憨憨');
          Query OK, 2 rows affected (0.47 sec)
          Records: 2  Duplicates: 0  Warnings: 0mysql> select * from t3;
          +----+-----------+------+
          | id | name      | sex  |
          +----+-----------+------+
          |  1 | 皮皮寒    | 男   |
          |  2 | 铁憨憨    | 男   |
          +----+-----------+------+
          2 rows in set (0.00 sec)
          # 使用delete删除后,在插入值,该字段还会延续之前的序号增长
          mysql> delete from t3;
          Query OK, 2 rows affected (0.57 sec)mysql> insert into t3(name) values('碎小梦');
          Query OK, 1 row affected (0.39 sec)mysql> select * from t3;
          +----+-----------+------+
          | id | name      | sex  |
          +----+-----------+------+
          |  3 | 碎小梦    | 男   |
          +----+-----------+------+
          1 row in set (0.00 sec)
          # 使用truncate可直接清空,从零开始
          mysql> truncate t3;
          Query OK, 0 rows affected (0.74 sec)mysql> insert into t3(name) values('皮皮寒');
          Query OK, 1 row affected (0.39 sec)mysql> select * from t3;
          +----+-----------+------+
          | id | name      | sex  |
          +----+-----------+------+
          |  1 | 皮皮寒    | 男   |
          +----+-----------+------+
          1 row in set (0.00 sec)
      4. foreign key

        外键约束:对应外表中的字段至少是unique的,推荐使用主键作为关联字段

        同过设置外键可以将两个或多个表关联起来

        # 创建父表
        mysql> create table department(-> id int primary key,-> name varchar(20) not null);
        Query OK, 0 rows affected (0.58 sec)# 创建子表,关联父表
        mysql> create table employee1(-> id int primary key,-> name varchar(20) not null,-> dpt_id int,-> foreign key(dpt_id)-> references department(id)    # 关联父表主键id-> on delete cascade    # 级联删除-> on update cascade);  # 级联更新
        Query OK, 0 rows affected (0.80 sec)# 先往父表中插入记录
        mysql> insert into department values(1,'教质部'),(2,'技术部'),(3,'人力资源部');
        Query OK, 3 rows affected (0.13 sec)
        Records: 3  Duplicates: 0  Warnings: 0# 再往子表中插入记录
        mysql> insert into employee1 values-> (1,'dama',1),-> (2,'debang',1),-> (3,'jiawen',2),-> (4,'yasuo',3),-> (5,'lakesi',2),-> (6,'yi',3);
        Query OK, 6 rows affected (0.54 sec)
        Records: 6  Duplicates: 0  Warnings: 0# 删除父表的记录,子表跟着删除
        mysql> delete from department where id=2;
        Query OK, 1 row affected (0.58 sec)mysql> select * from employee1;
        +----+--------+--------+
        | id | name   | dpt_id |
        +----+--------+--------+
        |  1 | dama   |      1 |
        |  2 | debang |      1 |
        |  4 | yasuo  |      3 |
        |  6 | yi     |      3 |
        +----+--------+--------+
        4 rows in set (0.00 sec)# 更新父表,子表中对应记录跟着改mysql> update department set id=2 where id=3;
        Query OK, 1 row affected (0.48 sec)
        Rows matched: 1  Changed: 1  Warnings: 0mysql> select * from employee1;
        +----+--------+--------+
        | id | name   | dpt_id |
        +----+--------+--------+
        |  1 | dama   |      1 |
        |  2 | debang |      1 |
        |  4 | yasuo  |      2 |
        |  6 | yi     |      2 |
        +----+--------+--------+
        4 rows in set (0.00 sec)
    • 修改表结构

      # 语法:
      # 1. 修改表名alter table 表名rename 新表名;
      # 2. 增加字段alter table 表名add 字段名 数据类型(完整性约束条件);
      # 3. 删除字段alter table 表名drop 字段名;
      # 4. 修改字段alter table 表名change 旧字段名 新字段名 旧数据类型(完整性约束条件);change 旧字段名 新字段名 新数据类型(完整性约束条件);modify 旧字段名 数据类型 (完整性约束条件);
      # 5. 修改字段排列顺序/在增加的时候指定字段位置alter table 表名add 字段名 数据类型(完整性约束条件) first;# 添加在第一列add 字段名 数据类型(完整性约束条件) after 字段名;    # 添加在此字段之后change与modify同理

      alter操作非空和唯一:

      create table t(id int unique,name char(10) not null);#去掉null约束
      alter table t modify name char(10) null;
      # 添加null约束
      alter table t modify name char(10) not null;# 去掉unique约束
      alter table t drop index id;
      # 添加unique约束
      alter table t modify id int unique;alter处理null和unique约束

      alter操作主键:

      # 先删除主键
      alter table table_test drop primary key;
      # 然后再增加主键
      alter table table_test add primary key(id);
      # 注:在增加主键之前,必须先把反复的id删除掉。

      为表添加外键:

      # 为book表添加外键
      alter table book add constraint fk_id foreign key(press_id) references press(id);
      # 删除外键
      alter table book drop foreign key fk_id;
    • 表与表的关系

      1. 一对多(或多对一):例如校区表与班级表

        校区表 一个校区可以有多个班级

        班级表 一个班级不可能对应多个校区

        校区表:校区id 校区名称 校区城市 校区地址

        班级表:班级id 班级名称 开班日期 班主任 校区id

        多(foreign key)关联一张表:班级表创建foreign key关联校区表的校区id字段

        mysql> create table school(id int primary key,sname varchar(20));
        Query OK, 0 rows affected (0.92 sec)mysql> desc school;
        +-------+-------------+------+-----+---------+-------+
        | Field | Type        | Null | Key | Default | Extra |
        +-------+-------------+------+-----+---------+-------+
        | id    | int(11)     | NO   | PRI | NULL    |       |
        | sname | varchar(20) | YES  |     | NULL    |       |
        +-------+-------------+------+-----+---------+-------+
        2 rows in set (0.02 sec)mysql> create table class(id int primary key,cname varchar(20),start char(8),-> sch_id int not null,-> foreign key(sch_id) references school(id) on delete cascade on update cascade);
        Query OK, 0 rows affected (0.83 sec)mysql> desc class;
        +--------+-------------+------+-----+---------+-------+
        | Field  | Type        | Null | Key | Default | Extra |
        +--------+-------------+------+-----+---------+-------+
        | id     | int(11)     | NO   | PRI | NULL    |       |
        | cname  | varchar(20) | YES  |     | NULL    |       |
        | start  | char(8)     | YES  |     | NULL    |       |
        | sch_id | int(11)     | NO   | MUL | NULL    |       |
        +--------+-------------+------+-----+---------+-------+
        4 rows in set (0.02 sec)mysql> insert into school values(1,'北京校区'),(2,'深圳校区'),(3,'上海校区');
        Query OK, 3 rows affected (0.47 sec)
        Records: 3  Duplicates: 0  Warnings: 0mysql> insert into class values(1,'三年一班','20180701',1),(2,'三年二班','20180701',1),(3,'四年一班','20180701',2),(4,'四年二班','20180701',3);
        Query OK, 4 rows affected (0.55 sec)
        Records: 4  Duplicates: 0  Warnings: 0mysql> select * from school;
        +----+--------------+
        | id | sname        |
        +----+--------------+
        |  1 | 北京校区     |
        |  2 | 深圳校区     |
        |  3 | 上海校区     |
        +----+--------------+
        3 rows in set (0.00 sec)mysql> select * from class;
        +----+--------------+----------+--------+
        | id | cname        | start    | sch_id |
        +----+--------------+----------+--------+
        |  1 | 三年一班     | 20180701 |      1 |
        |  2 | 三年二班     | 20180701 |      1 |
        |  3 | 四年一班     | 20180701 |      2 |
        |  4 | 四年二班     | 20180701 |      3 |
        +----+--------------+----------+--------+
        4 rows in set (0.00 sec)
      2. 多对多:例如作者和书

        一个作者可以写多本书

        一本书也可以有多个作者

        双向的一对多,即多对多。要形成对应关系需创建第三张表:一个字段是外键关联另一个表的主键,另一个字段外键关联另一张表的主键。

        mysql> create table author(-> id int primary key auto_increment,-> name varchar(20)-> );
        Query OK, 0 rows affected (0.34 sec)mysql> create table book(-> id int primary key auto_increment,-> name varchar(20)-> );
        Query OK, 0 rows affected (0.36 sec)mysql> insert into author(name) values ('江南'),('今何在');
        Query OK, 2 rows affected (0.13 sec)
        Records: 2  Duplicates: 0  Warnings: 0mysql> insert into book(name) values ('九州'),('龙族'),('悟空传');
        Query OK, 3 rows affected (0.13 sec)
        Records: 3  Duplicates: 0  Warnings: 0mysql> create table author_book(-> id int not null unique auto_increment,-> author_id int not null,-> book_id int not null,-> constraint fk_author foreign key(author_id) references author(id)-> on delete cascade-> on update cascade,-> constraint fk_book foreign key(book_id) references book(id)-> on delete cascade-> on update cascade,-> primary key(author_id,book_id)-> );
        Query OK, 0 rows affected (0.45 sec)mysql> insert into author_book(author_id,book_id) values-> (1,1),-> (1,2),-> (2,1),-> (2,3);
        Query OK, 4 rows affected (0.04 sec)
        Records: 4  Duplicates: 0  Warnings: 0mysql> desc author_book;
        +-----------+---------+------+-----+---------+----------------+
        | Field     | Type    | Null | Key | Default | Extra          |
        +-----------+---------+------+-----+---------+----------------+
        | id        | int(11) | NO   | UNI | NULL    | auto_increment |
        | author_id | int(11) | NO   | PRI | NULL    |                |
        | book_id   | int(11) | NO   | PRI | NULL    |                |
        +-----------+---------+------+-----+---------+----------------+
        3 rows in set (0.00 sec)mysql> select * from book;
        +----+-----------+
        | id | name      |
        +----+-----------+
        |  1 | 九州      |
        |  2 | 龙族      |
        |  3 | 悟空传    |
        +----+-----------+
        3 rows in set (0.00 sec)mysql> select * from author;
        +----+-----------+
        | id | name      |
        +----+-----------+
        |  1 | 江南      |
        |  2 | 今何在    |
        +----+-----------+
        2 rows in set (0.00 sec)mysql> select * from author_book;
        +----+-----------+---------+
        | id | author_id | book_id |
        +----+-----------+---------+
        |  1 |         1 |       1 |
        |  2 |         1 |       2 |
        |  3 |         2 |       1 |
        |  4 |         2 |       3 |
        +----+-----------+---------+
        4 rows in set (0.00 sec)
        
      3. 一对一

        关联方式:foreign key + unique

        mysql> create table customer(-> id int primary key auto_increment,-> name varchar(20) not null,-> qq varchar(10) not null,-> phone char(16) not null-> );
        Query OK, 0 rows affected (0.26 sec)mysql> create table student(-> id int primary key auto_increment,-> class_name varchar(20) not null,-> customer_id int unique,-> foreign key(customer_id) references customer(id)-> on delete cascade-> on update cascade-> );
        Query OK, 0 rows affected (0.54 sec)mysql> insert into customer(name,qq,phone) values-> ('皮皮寒','31811231','13811341220'),-> ('铁憨憨','123123123','15238383838'),-> ('碎小梦','283818181','18617171717');
        Query OK, 3 rows affected (0.15 sec)
        Records: 3  Duplicates: 0  Warnings: 0mysql> insert into student(class_name,customer_id) values-> ('龙吟',1),-> ('铁衣',2),-> ('碎梦',3);
        Query OK, 3 rows affected (0.14 sec)
        Records: 3  Duplicates: 0  Warnings: 0mysql> select * from student;
        +----+------------+-------------+
        | id | class_name | customer_id |
        +----+------------+-------------+
        |  1 | 龙吟       |           1 |
        |  2 | 铁衣       |           2 |
        |  3 | 碎梦       |           3 |
        +----+------------+-------------+
        3 rows in set (0.00 sec)

四、记录操作

转载于:https://www.cnblogs.com/yaoqi17/p/11285515.html

python之数据库-表操作相关推荐

  1. Python3.x的mysqlclient的安装、Python操作mysql,python连接MySQL数据库,python创建数据库表,带有事务的操作,CRUD

    1.数据库操作 1.1准备工作: 1.安装一个mysql数据库软件 2.创建一个数据库,test 3.在python的环境安装一个模块: MySQLdb 1.2 安装mysql的连接包 第一种:工具安 ...

  2. qt mysql怎么选表_Qt的Mysql数据库表操作(1)

    Qt中的QSqlDatabase.QSqlQueryModel.QSqlRecord.QSqlTableModel等类为我们提供了快速开发数据库的方式,支持多种数据库连接,例如oracle,db2,M ...

  3. 数据库表操作、数据类型及完整性约束

    数据库表操作.数据类型及完整性约束 库操作补充 数据库命名规则: 可以由字母.数字.下划线.@.#.$ 区分大小写 唯一性 不能使用关键字如 create select 不能单独使用数字 最长128位 ...

  4. python 添加数据库表_通过时间表(Python库)简化复杂的计划

    python 添加数据库表 by Maxim Mamaev 马克西姆·马马耶夫(Maxim Mamaev) 通过时间表(Python库)简化复杂的计划 (Make your complex sched ...

  5. MYSQL数据库表操作pdf

    <MYSQL数据库表操作pdf> 下载地址: 网盘下载 转载于:https://www.cnblogs.com/long12365/p/9731023.html

  6. python修改数据库表结构_python中数据库的相关操作-pymysql

    python3中可以使用库pymysql 数据准备: 搭建一个数据库,我是在docker下搭建的Mysql(端口号是3306,账号是root,密码123456) 建立数据库test_db,表TB_St ...

  7. python更新数据库表的时间字段_python更新数据库中某个字段的数据(方法详解)

    连接数据库基本操作,我把每一步的操作是为什么给大家注释一下,老手自行快进. 请注意这是连接数据库操作,还不是更新. import pymysql #导包 #连接数据库 db = pymysql.con ...

  8. 三 .数据库(表操作)

    一 .数据表(table) 1.数据表操作 创建表: 语法: create table 表名( 字段名1 类型[(宽度) 约束条件], 字段名2 类型[(宽度) 约束条件], 字段名3 类型[(宽度) ...

  9. 5.15 mysql 数据库(数据库/表操作/索引/pymysql/备份与恢复/事务/锁) 学习笔记

    文章目录 1 初始数据库 1)数据库 2)mysql 3)和用户权限相关的 4)基本操作 2 表操作 1)存储引擎 2)表和数据的一些基本操作 3)mysql中的数据类型 4)表的完整性约束 5)修改 ...

最新文章

  1. TP、TN、FP、FN
  2. 使用WMI对象收集计算机信息
  3. linux eclipse 头文件路径,Eclipse CDT标准库头文件设置
  4. 《妖猫传》大唐盛世背后那些事
  5. tar+openssl加密压缩解压缩
  6. linux上soul网关开通,soul 网关入门篇(一):搭建篇
  7. 独角访谈 | 去中心化交易所领军人物–Loi Luu
  8. eclipse 设置默认编码为Utf-8
  9. Visual Leak Detector(vld)无法显示内存泄露文件名称与行号
  10. flutetr dio 拦截器实现 token 失效刷新
  11. java简单代码练习
  12. 如何将时间字体LED化(类似电子表)显示
  13. ThinkPHP 汉字转成多种形式拼音
  14. azure mysql on vnet_Azure Database for MySQL (2) VNET rules
  15. java 音频波形图_java读取wav文件(波形文件)并绘制波形图的方法
  16. 中国大学排名是怎样的?
  17. everedit 格式化json_Visual studio code (VS code)
  18. android气泡样式图片,Android实现三角形气泡效果方式汇总
  19. android 360加固保
  20. asp.net web快速开发mvc网站框架源码

热门文章

  1. Hadoop——MapReduce相关eclipse配置及Api调用(图文超详细版)(内含遇到错误的解决方法)
  2. 应用该不该为视网膜显示屏而优化?这是个问题
  3. python关键字参数必须位于位置参数之前_python函数中的参数(关键字参数,默认参数,位置参数,不定长参数)...
  4. idou老师教你学Istio: 如何用Istio实现K8S Egress流量管理
  5. 求取SHP文件的最小外接矩形并裁剪图像
  6. 他本硕博连跨3大专业,毕业后没多久被破格聘为985高校教授!
  7. 【转】十大顶级奢侈品服装品牌
  8. 手机通讯录系统(三层架构+JDBC+MySQL)
  9. android 6g 有必要吗,Android手机6GB内存有必要吗?实测出真知
  10. Java POI 导入Excell