Mysql表相关操作-数据类型-完整性约束

事物的四大特性

float(255,30) 最大

create table t1(id int unsigned) 去标记 只能是正数

select @@sql_mode;

select @@global.sql_mode;

设置严格模式 STATIC_TRANS_TABLES;

事务

事务4大特性:
事务是由一组SQL语句组成的逻辑处理单元,事务具有ACID属性。
   原子性(Atomicity):事务是一个原子操作单元。在当时原子是不可分割的最小元素,其对数据的修改,要么全部成功,要么全部都不成功。
  一致性(Consistent):事务开始到结束的时间段内,数据都必须保持一致状态。
  隔离性(Isolation):数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的"独立"环境执行。
  持久性(Durable):事务完成后,它对于数据的修改是永久性的,即使出现系统故障也能够保持。

表相关操作

创建表

创建表完整语句
create table 表名(
    字段名1 类型[(宽度) 约束条件],
    字段名2 类型[(宽度) 约束条件],
    字段名3 类型[(宽度) 约束条件]
);

数据类型

数值类型

整型类型测试
mysql> create table t1(money tinyint);  #注意,创建表时最后一个字段后面不能有逗号,错误写法mysql> create table t1(money tinyint,);

mysql> insert into t1 values(11);
Query OK, 1 row affected (0.28 sec)

mysql> select * from t1;

mysql> insert into t1 values(-10);
Query OK, 1 row affected (0.11 sec)

mysql> select * from t1;

mysql> insert into t1 values(-200);
Query OK, 1 row affected, 1 warning (0.10 sec)

mysql> select * from t1;

设置了数据类型,会有一个约束效果,只能表示自己范围内的数

创建无符号数值类型的写法:
mysql> create table t2(id tinyint unsigned);
浮点型
测试
mysql> create table t3(id float(60,30));
Query OK, 0 rows affected (1.70 sec)

mysql> create table t4(id double(60,30));
Query OK, 0 rows affected (0.88 sec)

mysql> create table t5(id decimal(60,30));
Query OK, 0 rows affected (0.96 sec)

mysql> insert into t3 values(1.1111111111111111111111);
Query OK, 1 row affected (0.13 sec)

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

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

mysql> select * from t3;
mysql> select * from t4;
mysql> select * from t5;

日期类型

mysql> create table t6(d1 year ,d2 date,d3 datetime);
Query OK, 0 rows affected (1.75 sec)

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

mysql> select * from t6;

sql模式

:注意,一定要用严格模式
模式设置和修改(以解决上述问题为例):

    方式一:先执行select @@sql_mode,复制查询出来的值并将其中的NO_ZERO_IN_DATE,NO_ZERO_DATE删除,然后执行set sql_mode = '修改后的值'或者set session sql_mode='修改后的值';,例如:set session sql_mode='STRICT_TRANS_TABLES';改为严格模式 #session可以不用写

        此方法只在当前会话中生效,关闭当前会话就不生效了。

    方式二:先执行select @@global.sql_mode,复制查询出来的值并将其中的NO_ZERO_IN_DATE,NO_ZERO_DATE删除,然后执行set global sql_mode = '修改后的值'。

    此方法在当前服务中生效,重新MySQL服务后失效
    方法三:在mysql的安装目录下,或my.cnf文件(windows系统是my.ini文件),新增 sql_mode = STRICT_TRANS_TABLES

添加my.cnf如下:
[mysqld]            sql_mode=ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER

字符串类型

char和varchar

char和varchar性能对比:
    以char(5)和varchar(5)来比较,加入我要存三个人名:sb,ssb1,ssbb2
    char:
      优点:简单粗暴,不管你是多长的数据,我就按照规定的长度来存,5个5个的存,三个人名就会类似这种存储:sb ssb1 ssbb2,中间是空格补全,取数据的时候5个5个的取,简单粗暴速度快
      缺点:貌似浪费空间,并且我们将来存储的数据的长度可能会参差不齐

    varchar:
      varchar类型不定长存储数据,更为精简和节省空间
      例如存上面三个人名的时候类似于是这样的:sbssb1ssbb2,连着的,如果这样存,请问这三个人名你还怎么取出来,你知道取多长能取出第一个吗?(超哥,我能看出来啊,那我只想说:滚犊子!)
      不知道从哪开始从哪结束,遇到这样的问题,你会想到怎么解决呢?还记的吗?想想?socket?tcp?struct?把数据长度作为消息头。

      
      所以,varchar在存数据的时候,会在每个数据前面加上一个头,这个头是1-2个bytes的数据,这个数据指的是后面跟着的这个数据的长度,1bytes能表示2**8=256,两个bytes表示2**16=65536,能表示0-65535的数字,所以varchar在存储的时候是这样的:1bytes+sb+1bytes+ssb1+1bytes+ssbb2,所以存的时候会比较麻烦,导致效率比char慢,取的时候也慢,先拿长度,再取数据。

      优点:节省了一些硬盘空间,一个acsii码的字符用一个bytes长度就能表示,但是也并不一定比char省,看一下官网给出的一个表格对比数据,当你存的数据正好是你规定的字段长度的时候,varchar反而占用的空间比char要多。

Value   CHAR(4) Storage Required    VARCHAR(4)  Storage Required
''  '    '  4 bytes ''  1 byte
'ab'    'ab  '  4 bytes 'ab'    3 bytes
'abcd'  'abcd'  4 bytes 'abcd'  5 bytes
'abcdefgh'  'abcd'  4 bytes 'abcd'  5 bytes
        
      缺点:存取速度都慢
  总结:
    所以需要根据业务需求来选择用哪种类型来存
    其实在多数的用户量少的工作场景中char和varchar效率差别不是很大,最起码给用户的感知不是很大,并且其实软件级别的慢远比不上硬件级别的慢,所以你们公司的运维发现项目慢的时候会加内存、换nb的硬盘,项目的效率提升的会很多,但是我们作为专业人士,我们应该提出来这样的技术点来提高效率。

    但是对于InnoDB数据表,内部的行存储格式没有区分固定长度和可变长度列(所有数据行都使用指向数据列值的头指针),因此在本质上,使用固定长度的CHAR列不一定比使用可变长度VARCHAR列性能要好。因而,主要的性能因素是数据行使用的存储总量。由于CHAR平均占用的空间多于VARCHAR,因此使用VARCHAR来最小化需要处理的数据行的存储总量和磁盘I/O是比较好的。

    所以啊,两个选哪个都可以,如果是大型并发项目,追求高性能的时候,需要结合你们服务器的硬件环境来进行测试,看一下char和varchar哪个更好,这也能算一个优化的点吧~~~~

枚举和集合类型

枚举类型(enum)
An ENUM column can have a maximum of 65,535 distinct elements. (The practical limit is less than 3000.)
示例:
CREATE TABLE shirts (
name VARCHAR(40),
size ENUM('x-small', 'small', 'medium', 'large', 'x-large')
                );
    INSERT INTO shirts (name, size) VALUES ('dress shirt','large'), ('t-shirt','medium'),('polo shirt','small');

  
集合类型(set)
A SET column can have a maximum of 64 distinct members.
示例:
    CREATE TABLE myset (col SET('a', 'b', 'c', 'd'));
    INSERT INTO myset (col) VALUES ('a,d'), ('d,a'), ('a,d,a'), ('a,d,d'), ('d,a,d');

完整性约束

not null 不为空

create table t1(name char(10) not null);

default 默认值

create table t1(name char(10) not null default 'xx');

unique #唯一,字段数据不能重复

create table t1(name char(10) unique);

primary key #主键 约束效果:不为空且唯一 not null + unique

create table t1(id int primary key);

auto_increment 自增

create table t1(id int primary key auto_increment); 前面必须是个key

foreign key #外键 建立表关系使用的约束条件

多对一 (一对多)

在多的表里面添加一个字段,并给这个字段加foreign key,比如:
出版社对应书籍是多对一的关系
1.先创建出版社表  publish表
2.创建书籍表,外键写法:
    create table book(
        id int primary key,
        name char(10),
        pid int,
        foreign key(pid) references publish(id)
        );
3.先给出版社插入数据

一对一关系
学生表(student)和客户表(customer)
create table student(
        id int primary key,
        name char(10),
        cid int unique,
        foreign key(cid) references customer(id)
        );

多对多关系
作者表和书籍表
需要借助第三张表来完整两者的关系记录
第三张表后创建
create table authortobook(
        id int primary key,
        author_id int,
        book_id int,
        foreign key(author_id) references author1(id),
        foreign key(book_id) references book1(id)
        );

约束

  • unsigned 数字
  • not null 非空
  • default 设置默认值
  • unique
    • 唯一
    • 联合唯一 unique(ip,port)
  • auto_increment
    • 自增 针对int
    • 自带 not null
    • 至少需要设置unique才能设置auto_increment
    • 不受删除影响,记录增加过的值,失败也算
  • primary key
    • 相当于非空+唯一
    • 一张表只能有一个
    • 联合主键
  • foreign key
    • 外键
    • 级联更新 on update cascade
    • 级联删除 on delete cascade

数据插入操作

  • insert into class3 select * from class;
  • insert into class3(id,name) select id,name from class;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。