SQL-MySQL


SQL 组成

SQL
DML
DDL
select
update
insert
delete
create databases
alter
create table
drop table
create index
drop index
alter table
alter databases

sql资料链接

数据类型:https://www.yiibai.com/sql/sql-data-types.html;

运算符:https://www.yiibai.com/sql/sql-operators.html;

SQL 查询语句

SELECT * FROM

  • SELECT 语句执行顺序:select –>where –> group by–> having–>order by

  • SQL SELECT语法

SELECT column_name1,column_name2 FROM Table_name;/*(查询指定列数据)。*/
SELECT * FROM Table_name;/*(查询所有数据)。*/

SELECT DISTINCT;

  • SQL SELECT DISTINCT语法
SELECT DISTINCT column_name1,column_name2 FROM Table_name;
//实例
SELECT DISTINCT column_name1 FROM Table_name;

WHERE

  • WHERE子句用于过滤记录提取满足条件的记录

  • SQL WHERE 语法

SELECT column_name1,column_name2 FROM Table_name WHERE column_name1 operator
value;
/*实例*/
SELECT * FROM SQLStudy WHERE country='CN';
  • WHERE子句运算符

    • MySQL 的 WHERE 子句的字符串比较是不区分大小写的。 你可以使用 BINARY 关键字来设定 WHERE 子句的字符串比较是区分大小写的。
    运算符描述
    =等于
    <>不等于(在SQL一些版本中可写作!=)
    >大于
    <小于
    >=大于等于
    <=小于等于
    BETWEEN在某个范围
    LIKE搜索某种模式
    IN指定针对某个列的多个可能值
  • 通配符(在SQL中通配符与LIKE一起搭配使用):

    通配符描述
    %替代零个或多个字符
    _替代该位置一个字符(匹配开头是任意字母后面是指定内容的文本)
    [charlist]字符列表中的任何单一字符
    [^charlist] or [!charlist]不在字符列表中的任何单一字符
    • 通配符的使用:

      • % 通配符:

        /*匹配name列中开头是‘G’的所有数据*/
        SELECT * FROM SQLStudy WHERE name LIKE 'G%'
        /*匹配name列中结尾是‘k’的所有数据*/
        SELECT * FROM SQLStudy WHERE name LIKE '%k'
        /*匹配name列中包含‘oo’的所有数据*/
        SELECT * FROM SQLStudy WHERE name LIKE '%oo%'
        
      • _ 通配符:

        SELECT * FROM SQLStudy WHERE name LIKE '_oogle';
        SELECT * FROM SQLStudy WHERE name LIKE 'G_o_le';
        SELECT * FROM SQLStudy WHERE url LIKE '%_.com%';
        
      • [charlist] [!charlist]通配符:

        /*匹配name列中所有以g,F,s开头的数据*/
        SELECT * FROM SQLStudy WHERE name RLIKE '^[gFs]';
        /*匹配name列中所有以A ~ H开头的数据*/
        SELECT * FROM SQLStudy WHERE name RLIKE '^[A-H]';
        /*匹配name列中所有不是以A ~ H开头的数据*/
        SELECT * FROM SQLStudy WHERE name RLIKE '^[^A-H]';
        
      • 符号含义示例
        ^匹配字符串开始位置^a:表示任意以a开头的字符串。
        $匹配字符串结束位置a$:表示任意以a结尾的字符串。
        .匹配任意字符包括回车,换行
        * or +匹配零个 or 一个或多个字符在他之前必须有内容(*号可以是出现零次,+号至少出现一次)a*:表示前面有a后面是任意字符。
        匹配零次或一次

        a* 可以写成 a{0,}

        a+ 可以写成 a{1,}

        a? 可以写成 a{0,1}

  • LIKE 操作符(LINK 操作符用于在 WHERE 子句中搜索列中的指定模式)

    • SQL LIKE 语法

      SELECT * FROM SQLStudy WHERE column_name LIKE pattern;
      
    • 实例

      /*查找name列中以"G"开头的所有记录*/
      SELECT * FROM SQLStudy WHERE name LIKE 'G%'
      /*选取name列中以字母"k"结尾的所有记录*/
      SELECT * FROM SQLStudy WHERE name LIKE '%k';
      /*选取name列中包含模式"oo"的所有记录*/
      SELECT * FROM SQLStudy WHERE name LIKE '%oo%';
      
    • NOT(取反:获取不匹配记录)

      /*获取name列中不符合‘%oo%’匹配模式的记录*/
      SELECT * FROM SQLStudy WHERE name NOT LIKE '%oo%';
      
  • IN 操作符:

    • IN 操作符允许在 WHERE 子句中规定多个值。

    • IN 语法:

      SELECT * FROM Table_name WHERE column_name IN (value1,value2,...);
      
    • IN 与 = 的异同:

      • 同:均在WHERE中使用作为结果集的筛选条件。
      • 异:IN可以规定多个值,等于只能规定一个值。
    • IN 与 = 的转化:

      /*IN操作符获取两个多条记录*/
      SELECT * FROM SQLStudy WHERE column1 IN (value1,value2);
      /*与IN操作符等价的=号操作符*/
      SELECT * FROM SQLStudy WHERE column1=value1 OR column1=value2;
      
  • BRTWEEN操作符:

    • BETWEEN操作符用于选取两个值之间范围的记录;

    • 语法:

      SELECT * FROM Table_name WHERE column_name BETWEEN value1 AND value2;
      
      /*示例:获取SQLStudy表中id值在1 ~ 4之间的记录*/
      SELECT * FROM SQLStudy WHERE id BETWEEN 1 AND 4;
      /*获取不在某个范围内的数据 NOT BETWEEN*/
      SELECT * FROM SQLStudy WHERE id NOT BETWEEN 1 AND 4;
      /*带有 IN 的BETWEEN操作符示例*/
      SELECT * FROM SQLStudy WHERE (alexa BETWEEN 1 AND 20) AND country NOT IN ('USA','IND');
      /*带有文本的BETWEEN操作符示例:获取name中A ~ H开头的记录*/
      SELECT * FROM SQLStudy WHERE name BETWEEN 'A' AND 'H';
      /*带有日期的BETWEEN操作符实例*/
      SELECT * FROM access_log WHERE date BETWEEN '2016-05-10' AND '2016-05-14';
      
  • 注意!

    • 在某些数据库中,BETWEEN 选取介于两个值之间但不包括两个测试值的字段。
    • 在某些数据库中,BETWEEN 选取介于两个值之间且包括两个测试值的字段。
    • 在某些数据库中,BETWEEN 选取介于两个值之间且包括第一个测试值但不包括最后一个测试值的字段。

SQL SELECT TOP、LIMIT、ROWNUM子句

SELECT TOP子句用于规定要返回的记录数目。(并非所有数据库系统都支持SELECT TOP语句,MySQL支持LIMIT选取指定数量的数据条数,Oracle支持ROWNUM选取指定数量的数据条数)。

  • 语法

    • SQL Server / MS Access

      SELECT TOP number FROM Table_name;
      or
      percent column_name(s) FROM Table_name;
      
    • MySQL

      SELECT column_name(s) FROM Table_name LIMIT number;
      //实例
      SELECT * FROM SQLStudy LIMIT 2;
      
    • Oracle

      SELECT column_name(s) FROM Table_name WHERE ROWNUM<=number;
      
    • 返回数据后N行

      /*先降序排列然后选取一定条目的数据*/
      SELECT * FROM Table_name ORDER BY id DESC LIMIT N;
      
    • SQL 文本字段与数字

      • SQL 使用单引号包围文本字段(大部分数据库系统也支持双引号);
      • 如果是数值字段则不用引号;
    • SQL AND & OR 运算符

    • 基于一个以上条件对记录进行过滤;

    • SELECT * FROM SQLStudy WHERE country='USA' OR alexa=1;
      SELECT * FROM SQLStudy WHERE country='USA' OR country='CN';
      /* AND 与 OR 混合使用 */
      SELECT name FROM SQLStudy WHERE (country='USA' AND alexa>1) OR name='google';
      

ORDER BY

  • 注释

    • ORDER BY:用于对结果集按照一个列或者多个列进行排序。
    • ORDER BY:默认按照升序对记录进行排序如果需要降序排列则可以使用DESC。
  • 在 MySQL 中如果是 GBK 编码直接在后面加上 ORDER BY 如果是 utf-8 编码则需要转码(ORDER BY(column using gbk))

  • SQL ORDER BY语法:

    SELECT * FROM SQLStudy ORDER BY column_name1,column_name2 ASC|DESC;
    
    • 实例
     /*默认升序排列*/
     SELECT * FROM SQLStudy ORDER BY alexa;
     /*DESC参数降序排列*/
     SELECT * FROM SQLStudy ORDER BY alexa DESC;
    
    • ORDER BY多列排序

      SELECT * from SQLStudy ORDER BY country,alexa;
      

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Is3tJ04k-1594707862265)(C:\Users\l\AppData\Roaming\Typora\typora-user-images\image-20200313161332078.png)]

      在对多个列进行排序时:先按照第一个列进行排序在第一列排序完成后在第一次排序的基础上对第二列进行排序。

      • 1,先将country值这一列排序,同为CN的排前面,同属USA的排后面;
      • 2,然后在同属CN的这些多行数据中,再根据alexa值的大小排列;
      • 3,ORDER BY排序时,不写明ASC DESC的时候,默认是ASC(升序);
      • 4,对于升序与降序可以单独对某一列使用;

SQL插入语句

INSERT INTO

  • INSERT INTO语法

    • 不需要指定插入数据的列名,只需提供插入的值即可;

      INSERT INTO Table_naem VALUES (Value1,Value2,...);
      
    • 需要指定列名以及被插入的值;

      INSERT INTO Table_name (column1,column2,...) VALUES (Value1,Value2,...);
      
    • 示例:

      /*插入一条完整记录*/
      INSERT INTO SQLStudy (name,url,country,alexa) VALUES ('百度','httpd://baidu.com/','CN','4');
      /*插入指定记录*/
      INSERT INTO SQLStudy (name,url,country) VALUES ('stackoverflow', 'http://stackoverflow.com/', 'IND');
      /*两种方式的区别:如果没有指定列名则需要提供整行的完整数据,指定列名的可以只提供对应的值。*/
      
    • 第一列如果没有设置主键自增(PRINARY KEY AUTO_INCREMENT)的话添加第一列数据比较容易错乱,要不断的查询表看数据。

      如果添加过主键自增(PRINARY KEY AUTO_INCREMENT)第一列在增加数据的时候,可以写为0或者null,这样添加数据可以自增, 从而可以添加全部数据,而不用特意规定那几列添加数据。


SQL更新语句

UPDATE语句

  • UPDATE语法:

    UPDATE Table_name SET column1=value1,column2=value2 WHERE some_column=some_value;
    
    • 示例:

      UPDATE SQLStudy SET country='USA',alexa=5000 WHERE name='菜鸟教程';
      
  • 提示:

    WHERE语句规定了哪条或者哪些记录需要更新,如果忽略了WHERE语句将会更新所有数据。

    在 MySQL 中可以通过设置 sql_safe_updates 这个自带的参数来解决,当该参数开启的情况下,你必须在update 语句后携带 where 条件,否则就会报错。set sql_safe_updates=1;标识开启该功能

  • UODATE 替换某个字段中的某个字符

    /*批量修改某个字段中的某个字符*/
    UPDATE Table_name SET column=REPLACE(column,'ord_str',"new_str");
    

SQL删除语句

DELETE语句

  • DELETE语法:

    /* 删除所有数据或者时部分数据(取决于WHERE 后面的条件) */
    DELETE FROM Table_name WHERE some_column=some_value;
    
    • 示例

      idnameurlalexacountry
      1googlehttp://www.google.cm/1USA
      2淘宝https://www.taobao.com/13CN
      3菜鸟教程https://www.runoob.com/5000USA
      4Facebookhttps://www.facebook.com/3USA
      5微博Http://weibo.com/20CN
      6百度https://www.baidu.com/4CN
      7stackoverflowhttp://stackoverflow.com/0IND
      8百度HTTPS://www.baidu.com/5USA
      DELETE FROM SQLStudy WHERE name='百度' AND country='CN';
      /*不删除表的情况下删除所有记录,表结构、属性、索引保持不变。*/
      DELETE FROM SQLStudy;
      DELETE * FROM SQLStudy;
      
      idnameurlalexacountry
      1googlehttp://www.google.cm/1USA
      2淘宝https://www.taobao.com/13CN
      3菜鸟教程https://www.runoob.com/5000USA
      4Facebookhttps://www.facebook.com/3USA
      5微博Http://weibo.com/20CN
      7stackoverflowhttp://stackoverflow.com/0IND
      8百度HTTPS://www.baidu.com/5USA
  • 关于DROP、TRUNCATE、DELETE的区别:

    • DROP
    DROP Table_name;
    

    删除表Table_name,不管是 Innodb 和 MyISAM,立即释放空间,将表彻底删除干净。

    • TRUNCATE

      TRUNCATE Table_name;
      

      快速删除表Table_name的内容,不管是 Innodb 和 MyISAM,立即释放空间,不删除表的定义,表的结构还在(数据不可恢复)。

    • DELETE

      /*删除指定数据*/
      DELETE FROM SQLStudy WHERE alexa=3 AND country='US';
      

      带条件的删除,表结构不变,不管是 innodb 还是 MyISAM 都不会释放磁盘空间;

      /*删除所有数据*/
      DELETE FROM SQLStudy;
      
      
    

不带条件可以删除表中的所有数据,保留表的定义,Innodb 不释放空间(删除后数据保存在回滚段中,可恢复)。

delete 操作以后,使用 optimize table table_name 会立刻释放磁盘空间,不管是 innodb 还是 myisam;

  • 执行速度

    DROP > TRUNCATE > DELETE

    • 相同点:

      相同不同
      三者都能删除数据DELETE删除的数据能恢复,TRUNCATE和DROP不能恢复。
      DROP删除的是整个表,DELETE和TRUNCATE是删除的表中数据。
      DROP不保留表结构和表定义,DELETE和TRUNCATE保留。
      DELETE不释放空间,DROP和TRUNCATE释放空间。

SQL 别名

  • 为表名称或列名称指定别名;

  • 列的 SQL 别名语法:

    SELECT column1 AS col1 FROM SQLStudy; 
    /*合并列*/
    SELECT id,CONCAT(name,',',url,',',alexa,',',country) AS site_info FROM SQLStudy;
    
  • 表的 SQL 别名语法(常用于多表查询):

    /*同时查询SQLStudy和access_log两个表中*/
    SELECT S.name,S.url,A.site_id,A.count FROM SQLStudy AS S,access_log AS A WHERE (S.alexa BETWEEN 1 AND 5) AND (A.aid BETWEEN 1 AND 4);
    
  • 在下面的情况下,使用别名很有用:

    • 在查询中涉及超过一个表
    • 在查询中使用了函数
    • 列名称很长或者可读性差
    • 需要把两个列或者多个列结合在一起

SQL 连接

INNER JOIN

  • INNER JOIN(INNER可省略)关键词在表中至少存在一个匹配时返回行;

  • INNER JOIN语法:

    SELECT * FROM Table1 AS T1 JOIN Table2 AS T2 ON T1.column1=T2.column1;
    
    SELECT * FROM SQLStudy AS S JOIN access_log AS A ON S.columnS=A.columnA ORDER BY S.columnS;
    
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1iw5XqAq-1594707862269)(C:\Users\l\AppData\Roaming\Typora\typora-user-images\image-20200314165122045.png)]

    注释:INNER JOIN 关键字在表中存在至少一个匹配时返回行。如果 “SQLStudy” 表中的行在 “access_log” 中没有匹配,则不会列出这些行。

  • 在使用 JOIN 时,ON 和 WHERE 的区别:

    1. on 条件是在生成临时表时使用的条件,它不管 on 中的条件是否为真,都会返回左边表中的记录。
    2. where 条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经没有 left join 的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉。

LEFT JOIN && RIGHT JOIN

  • LEFT JOIN:从左表返回所有行,如果右表中的数据不匹配则显示为 NULL。

  • LEFT JOIN 语法:

    SELECT * FROM SQLStudy AS S LEFT JOIN access_log AS A ON S.columnS=A.columnA ORDER BY S.columnS;
    /*注释:在某些数据库中 LEFT JOIN 称为 LEFT OUTER JOIN*/
    
  • RIGHT JOIN:RIGHT JOIN 关键字从右表返回所有的行,即使左表中没有匹配。如果左表中没有匹配,则结果为 NULL。

  • RIGHT JOIN 语法:

    SELECT * FROM access_log AS A RIGHT JOIN SQLStudy AS S ON S.columnS=A.columnA ORDER BY S.columnS;
    

FULL OUTER JOIN

  • FULL OUTER JOIN 关键字只要左表和右表其中一个表中存在匹配,则返回行 FULL OUTER JOIN 关键字结合了 LEFT JOIN 和 RIGHT JOIN 的结果。(MySQL不支持 FULL OUTER JOIN)。

SQL UNION 操作符

  • UNION 操作符用于和并两个或多个 SELECT 语句的结果;

  • __注意:__UNION 中的每个 SELECT 语句必须有相同的列数,并且每一列的数据类型相似,同时每个 SELECT 语句中的列必须有相同的顺序;

  • UNION 语法:

    /*默认 UNION 选取不同的值 如果允许重复则选用 UNION ALL*/
    SELECT * FROM SQLStudy UNION SELECT * FROM access_LOG;
    SELECT * FROM SQLStudy UNION ALL SELECT * FROM access_log;
    /*UNION 结果集的列名总是第一个 SELECT 语句中的列名*/
    

    使用UNION命令时需要注意,只能在最后使用一个ORDER BY命令,是将两个查询结果合在一起之后,再进行排序!绝对不能写两个ORDER BY命令。

    另外,在使用ORDER BY排序时,注意两个结果的别名保持一致,使用别名排序很方便。当然也可以使用列数。


SQL SELECT INTO 语句

  • SQL SELECT INTO 语句从一个表查询数据插入到另一个表中;

  • Mysql 不支持 SELECT INTO 但是支持 INSET INTO … SELECT;

    /*拷贝表结构和表数据*/
    CREATE TABLE Table_Copy AS SELECT * FROM Table;
    

INSERT INTO SELECT 语句

  • INSERT INTO SELECT:语句从一个表复制数据,然后插入到一个**已存在的表,**目标表中任何已存在的行都不会受影响;

  • INSERT INTO SELECT语法:

    • 从一个表复制所有列插入到另一个已存在的表中;

      INSERT INTO Table2 SELECT * FROM Table1;
      
    • 复制想要的列插入到已存在的表;

      • 将 Table1 表中的数据插入到 Table2 中其他没有数据插入的列 NULL 填充
      INSERT INTO Table2 (column1,column2...) SELECT column1,column2,... FROM Table1;
      

CREATE DATABASE

  • 语法:

    CREATE DATABASE DBNAME; 
    

CREATE TABLE

  • CREATE TABLE 语句用于创建数据库中的表。表由行和列组成,每个表都必须有个表名。

  • CREATE TABLE 语法:

    CREATE TABLE TableName 
    (
        id INT UNSIGNED AUTO_INCREMENT,
        column1 data_type(size),
        column2 data_type(size),
        column3 data_type(size),
        ...
        PRIMARY KEY ('id')
    )ENGINE=InnoDB DEFAULT CHARSET=utf-8;
    

    column:规定列的名称;

    data_type:列的数据类型;

    size:数据长度;

    AUTO_INCREMENT:定义列的自增属性;

    PRIMARY KEY:设置主键;

    ENGINE:设置引擎;

    CHARSET:设置数据库字符集为utf-8;

  • MySQL数据类型:在MySQL中有三种主要类型 Text(文本),Number(数字),Date/Time(日期/时间)

SQL 约束

  • 约束类型:

    • NOT NULL:规定某列值不能为存储为 NULL;
    • UNIQUE:保证某列的每行必须有唯一的值;
    • PRIMARY KEY:NOT NULL 和 UNIQUE 的结合,确保某列(或两个列多个列的结合)有唯一标识
    • FOREIGN KEY:保证一个表中的数据匹配零一个表中的值;
    • CHECK:保证列中的值符合指定条件;
    • DEFAULT:规定没有给列赋值时的默认值;
  • NOT NULL:

    • 在默认情况下,表的列接受 NULL;

    • NOT NULL:始终强制字段包含值,对于没有包含值的数据无法插入;

    • 添加 删除 NOT NULL 约束:

      ALTER TABLE Table_name MODIFY columnname column_data_type NOT NULL;
      ALTER TABLE Table_name MODIFY volumnname column_data_type NULL;
      
  • UNIQUE:

    • UNIQUE 约束唯一标识数据库表中的每条记录。

    • PRIMARY KEY 约束拥有自动定义的 UNIQUE 约束。

    • 每个表可以拥有多个 UNIQUE 约束但是只能拥有一个 PRIMARY KEY 约束。

    • 在创键表时给某一列添加 UNIQUE 约束:

      • MySQL
      CREATE TABLE Table_name 
      (
          P_id int NOT NULL,
          LastName varchar(255) NOT NULL,
          FirstName varchar(255),
          Address varchar(255),
          City varchar(255),
          UNIQUE (P_id)
      );
      
      • SQL Server / Oracle /MS Access:

        CREATE TABLE Persons
        (
            P_Id int NOT NULL UNIQUE,
            LastName varchar(255) NOT NULL,
            FirstName varchar(255),
            Address varchar(255),
            City varchar(255)
        )
        
    • 命名 UNIQUE 约束,并定义多个列的 UNIQUE 约束:

      • MySQL / SQL Server / Oracle / MS Access:

        CREATE TABLE TableName
        (
            P_Id int NOT NULL,
            LastName varchar(255) NOT NULL,
            FirstName varchar(255),
            Address varchar(255),
            City varchar(255),
            CONSTRAINT uc_PersonID UNIQUE (P_Id,LastName)
        )
        
    • 当表已经创建时添加 UNIQUE 约束:

      ALTER TABLE Persons ADD UNIQUE (P_Id);
      
    • 如需命名 UNIQUE 约束,并定义多个列的 UNIQUE 约束:

      ALTER TABLE Persons ADD CONSTRAINT uc_PersonsID UNIQUE (P_Id,LastName);
      
    • 撤销 UNIQUE 约束:

      //MySQL
      alter table Tablename drop index Constraint_name;
      //SQL Server / Oracle /MS Access
      alter table Tablename drop constraint Constraint_name;
      

      Constraint_name:代表添加约束时的约束名,如果没有给约束命名则为添加约束的列名

  • SQL PRIMARY KEY

    • 主键必须包含唯一的值。

    • 主键列不能包含 NULL。

    • 每个表都应该有一个主键,并且只能有一个主键。

    • 创建主键:

      • MySQL

        CREATE TABLE Table_name
        (
            P_Id int NOT NULL,
            LastName varchar(255) NOT NULL,
            FirstName varchar(255),
            Address varchar(255),
            City varchar(255),
            PRIMARY KEY (P_Id)//必须要用括号
        )
        
      • SQL Server / Oracle / MS Access:

        CREATE TABLE Table_name
        (
            P_Id int NOT NULL PRIMARY KEY,
            LastName varchar(255) NOT NULL,
            FirstName varchar(255),
            Address varchar(255),
            City varchar(255)
        )
        
      • 命名 PRIMARY KEY 约束,并定义多个列的 PRIMARY KEY 约束(实际上还是只有一个主键,只不过主键的内容由多个列组成,添加时必须确保这多个列的内容都不同才能添加成功):

        CREATE TABLE Persons
        (
            P_Id int NOT NULL,
            LastName varchar(255) NOT NULL,
            FirstName varchar(255),
            Address varchar(255),
            City varchar(255),
            constraint pk_PersonID PRIMARY KEY (P_Id,LastName)
        )
        
      • 创建表之后对主键进行修改:

        • 在某一列添加 PRIMARY KEY 约束:

          ALTER TABLE Table_name ADD PRIMARY KEY (P_Id);
          
        • 命名 PRIMARY KEY 约束并定义多个列的 PRIMARY KEY 约束:

        /*由于主键的唯一性,改变前需删除原来定义的主键*/
        /* 添加主键后主键包含列原来为 NULL 的会被修改为 NOT NULL */
        ALTER TABLE Table_name ADD CONSTRAINT uc_PersonID PRIMARY KEY (P_Id,LastName);
        
      • 删除主键:

        • MySQL

          ALTER TABLE TableName DROP PRIMARY KEY;
          
        • SQL Server / Oracle / MS Access

          ALTER TABLE Table_name DROP CONSTRAINT Constraint_name;
          
  • FOREIGN KEY 约束:

    • 外键(Foreign Key):如果表 A 中的一个字段 a 对应于表 B 的主键 b,则字段 a 称为表 A 的外键,此时存储在表 A 中字段 a 的值,要么是 NULL,要么是来自于表 B 主键 b 的值。

    • 一个表中的 FOREIGN KEY指向另一个表中的 UNIQUE KEY(惟一约束的键);

    • 在创建表时添加 FOREIFN KEY 约束指向 Persons 的 P_Id 列

      CREATE TABLE Table_name 
      (
          O_Id INT NOT NULL,
          OrderNo INT NOT NULL,
          P_Id INT NOT NULL,
          PRIMARY KEY (O_Id),
          FOREIGN KEY (P_Id) REFERENCES Persons(P_Id)
      )
      
    • 命名 FOREIDN KEY 约束并定义多个列的 FOREIGN KEY 约束:

      CREATE TABLE Table_name 
      (
          O_Id INT NOT NULL,
          OrderNo INT NOT NULL,
          P_Id INT,
          PRIMARY KEY (O_Id),
          CONSTARINT uc_ConstraintName FOREIGN KEY (P_Id)/*给P_Id添加FOREIDN KEY 约束并命令该约束为 uc_ConstraintName*/
          REFERENECES Persons(P_Id)/*该约束的列指向Person表的 P_Id 列*/
      )
      
    • 创建表之后添加 FOREIGN KEY 约束:

      ALTER TABLE Orders ADD FOREIGN KEY (P_Id) REFERENCES Persons (P_Id);
      
    • 添加 FOREIGN KEY 约束并进行命名:

      ALTER TABLE Orders ADD CONSTRAINT uc_FOREIGN FOREIGN KEY (P_Id) REFERENCES Persos(P_Id);
      
    • 撤除 FOREIGN KEY 约束:

      ALTER TABLE Orders DROP FOREIGN KEY uc_FOREIGN;
      
  • SQL CHECK 约束

    • 用于限制列中值的范围。对於单个列定义 CHECK 约束,那么该列只允许特定的值。对于表定义

      CHECK 约束,那么该约束将会基于每行的其他列的值在特定的列中对其值进行限制。



MySQL NULL 值处理

  • IS NULL:当列的值时 NULL,此运算符返回 true;
  • IS NOT NULL:当列的值不为 NULL,运算符返回 true;
  • <=>:比较操作符(不同于 = 运算符),当比较的两个值为都为 NULL 或者相等时返回 true
  • 在 MySQL 中,NULL 值与其它值的比较(即使是 NULL)永远返回 NULL


MySQL事务

  • MySQL 中只有 Innodb 引擎下的数据库或数据表才支持事务。

  • 事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句全部执行或全部不执行。

  • 事务用来管理 insert、update、delete 语句。

  • 事务满足的条件:

    1. 原子性:事务中的操作要么全部执行要么全部不执行,不会停留在中间的某一环节,事务执行出错会被回滚到事务开始前的状态就,像这个事务重来没被执行过一样。
    2. 一致性:在事务开始前和事务结束后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设条件,这包含资料的精确度,串联性以及后续数据库可以自发的完成预订的工作。
    3. 允许并发访问,隔离性可以防止并发访问时数据的交叉读写出错,事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
    4. 持久性:事务处理结束后,对数据的修改是永久的,即便是系统故障也不会丢失

    在 MySQL 命令行的默认设置下,事务都是自动提交的,即执行 SQL 语句后就会马上执行 COMMIT 操作。因此要显式地开启一个事务务须使用命令 BEGIN 或 START TRANSACTION,或者执行命令 SET AUTOCOMMIT=0,用来禁止使用当前会话的自动提交。



    数据库三范式

    • 作用:为建立数据冗余小,结构合理的数据库而遵循的规则。

    • 相关概念导入

      • 码: 一个表中,可以唯一决定一个元祖的属性“集合”。假设K为表中的某个属性,如果在K确定了的情况下,这个表里面的其他属性都可以确定,那么K就叫做码。比如通过ID可以获取到姓名,系名,系主任名,但是不确定课名和分数。课名可以获取分数。

        id------姓名,系名,系主任 课名------分数

        (id,课名)这个属性组就叫做码。

      • 依赖:函数依赖:函数y=f(x)代表了给定一个x的值,y的值也是确定的,那就说Y函数依赖与X,写作X—Y,比如:在表中,给定一个学号,必定能得到唯一的一个姓名。那就说姓名函数依赖与学号。写作:学号----姓名,在表中的函数依赖还有:学号------系名,学号-------系主任,(学号,课名)-----成绩

        完全函数依赖:在一张表中,若x—>y,且对于x的任何一个真子集(假如属性组x包含超过一个属性的话)x’,x’->y不成立,那么我们称y对于x完全函数依赖,记做XF—>y.比如(学号,课名)-----成绩,学号和课名都是x的真子集,但是如果只有学号,或者只有课名,是不能得到一个唯一的成绩,满足完全函数依赖的要求,所以y完全依赖与X。

        部分函数依赖:如果y函数依赖与x,但是y 不完全函数依赖与x,那就叫做部分函数依赖。比如(学号,课名)------姓名。由学号可以得到唯一的姓名,但是由课名不能得到唯一的姓名。所以称为y部分函数依赖x

    • 范式分类:

      1. 第一范式(确保每列保持原子性):所有字段的值都是不可分裂的原子值;

      2. 第二范式(确保表中的每列都和主键相关):一个表中只能保存一种数据,不可以把多种数据保存在一张表中

        比如要设计一个订单信息表,因为订单中可能会有多种商品,所以要将订单编号和商品编号作为数据库表的联合主键,如下表所示。

        在这里插入图片描述

        这样就产生一个问题:这个表中是以订单编号和商品编号作为联合主键。这样在该表中商品名称、单位、商品价格等信息不与该表的主键相关,而仅仅是与商品编号相关。所以在这里违反了第二范式的设计原则。

        而如果把这个订单信息表进行拆分,把商品信息分离到另一个表中,把订单项目表也分离到另一个表中,就非常完美了。如下所示。

        在这里插入图片描述

        这样设计,在很大程度上减小了数据库的冗余。如果要获取订单的商品信息,使用商品编号到商品信息表中查询即可。

      3. 第三范式(确保每列都和主键直接相关,而不是间接相关):

      4. 其实简单的说三范式是数据库设计中最基础的规则,第一范式不需要我们考虑太多,因为关系数据库已经帮我们控制好了;第二范式,就是要有主键,其他属性都要依赖于这个主键,再设计时尽量避免组合的主键,组合主键常常违背第二范式;第三范式,就是不能有冗余,一张表,只能有主键,依赖主键的属性,外键,不能包含外键表的非主键属性(外键表的非主键属性由表的外键在外键表中查询)

create table User_Address (address_id int(11) NOT NULL AUTO_INCREMENT,Province varchar(10) NOT NULL,City varchar(10) NOT NULL,County varchar(10) NOT NULL,id int(11) NOT NULL,constraint pk_constraint PRIMARY KEY (address_id),constraint fk_constraint FOREIGN KEY (id) references User_BaseInfo (id) on delete cascade)ENGINE=InnoDB DEFAULT CHARSET=utf8;
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值