• mysql基础语法速成版


    一、前言

    这里对mysql基础语法进行总结,以便用于复习回顾,对于需要安装教程的可以参看下面的文章。
    MySQL8安装教程

    二、基础语法

    2.1 数据库操作

    • 创建数据库
    create database 数据库名
    
    # 示例
    create database mydata
    # 或者,但不存在的时候创建数据库
    create database  if not exists mydata
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 删除数据库
    drop database 数据库名
    
    # 示例
    drop database test
    # 或者 但数据存在时删除
    drop database  if  exists test
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 使用数据库
    use 数据库名
    #eg:
    use mydata
    
    • 1
    • 2
    • 3

    2.2 MySQL数据类型

    mysql常用数据类型

    类型大小用途
    TINYINT1 Bytes小整数值
    INT或INTEGER4 Bytes大整数值
    FLOAT4 Bytes单精度
    浮点数值
    DOUBLE8 Bytes双精度
    浮点数值
    DECIMAL对DECIMAL(M,D) ,如果M>D,为M+2否则为D+2小数值
    DATE3 Bytes日期值
    TIME3 Bytes时间值或持续时间
    DATETIME8 Bytes混合日期和时间值
    TIMESTAMP4 Bytes混合日期和时间值,时间戳
    CHAR0-255 Bytes定长字符串
    VARCHAR0-65535 Bytes变长字符串
    TEXT0-65535 Bytes长文本数据

    2.3 表操作

    2.3.1 表的创建、删除,及表结构的改变

    • 创建表
    CREATE TABLE IF NOT EXISTS `test`(
       `id` INT UNSIGNED AUTO_INCREMENT, # 设置唯一性约束和自增
       `title` VARCHAR(100) NOT NULL,  # 设置字段不为空
       `author` VARCHAR(40) NOT NULL,
       `date` DATE,
       PRIMARY KEY ( `id` )   # 设置为主键
    )ENGINE=InnoDB DEFAULT CHARSET=utf8;
    # 设置引擎为innoDB 默认编码方式为utf8
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 删除表
    DROP TABLE table_name ;
    DROP TABLE if exists table_name    
    #eg
    DROP TABLE if exists test
    
    • 1
    • 2
    • 3
    • 4
    • alter命令修改表结构
      MySQL 的 ALTER 命令用于修改数据库、表和索引等对象的结构。
      ALTER 命令可以添加、修改或删除数据库对象,并且可以用于更改表的列定义、添加约束、创建和删除索引等操作。
    1. 修改表结构
      添加新列:
    ALTER TABLE table_name
    ADD column_name data_type;
    
    • 1
    • 2
    1. 修改列定义
    ALTER TABLE table_name
    MODIFY column_name new_data_type;
    
    # 修改默认值
     ALTER TABLE testalter_tbl ALTER i SET DEFAULT 1000;
     # 删除默认值
      ALTER TABLE testalter_tbl ALTER i DROP DEFAULT;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1. 修改列名称:
    ALTER TABLE table_name
    CHANGE old_column_name new_column_name data_type;
    
    • 1
    • 2
    1. 删除列:
    ALTER TABLE table_name
    DROP column_name;
    
    • 1
    • 2

    如果表只剩一个字段则无法使用drop进行删除
    5. 添加约束
    添加主键:

    ALTER TABLE table_name
    ADD PRIMARY KEY (column_name);
    
    • 1
    • 2
    1. 添加外键:
    ALTER TABLE table_name
    ADD FOREIGN KEY (column_name) REFERENCES referenced_table(ref_column_name);
    
    • 1
    • 2
    1. 添加唯一约束:
    ALTER TABLE table_name
    ADD CONSTRAINT constraint_name UNIQUE (column_name);
    
    • 1
    • 2
    1. 创建索引
      创建普通索引:
    ALTER TABLE table_name
    ADD INDEX index_name (column1 [ASC|DESC], column2 [ASC|DESC], ...);
    
    • 1
    • 2
    1. 创建唯一索引:
    ALTER TABLE table_name
    ADD UNIQUE INDEX index_name (column1 [ASC|DESC], column2 [ASC|DESC], ...);
    
    • 1
    • 2
    1. 删除索引:
    ALTER TABLE table_name
    DROP INDEX index_name;
    
    • 1
    • 2
    1. 重命名表:
    ALTER TABLE old_table_name
    RENAME TO new_table_name;
    
    • 1
    • 2
    1. 修改表存储引擎
    ALTER TABLE table_name ENGINE = new_storage_engine;
    
    • 1

    2.3.2表数据的增删改查

    • 插入数据
    # 语法1
    INSERT INTO table_name ( field1, field2,...fieldN )VALUES( value1, value2,...valueN );
    # 语法2
    INSERT INTO table_name values( value1, value2,...valueN );
    
    • 1
    • 2
    • 3
    • 4
    • 删除数据
    # 方式1
    DELETE FROM table_name [WHERE Clause]
    # 方式2 清空表的数据,
    TRUNCATE TABLE employees;
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    1. 如果没有指定 WHERE 子句,MySQL 表中的所有记录将被删除。
    2. 可以在 WHERE 子句中指定任何条件
    3. 可以在单个表中一次性删除记录。
    4. TRUNCATE关键字用于清空表中的所有数据,但不会删除表结构。它比DELETE关键字更快,因为它不记录任何删除操作,也不会在REDO日志中记录任何信息
    5. 需要注意的是,TRUNCATE关键字比DELETE关键字更危险,因为它不记录任何删除操作,因此无法撤销。
    • 查询数据
    # 语法1
    SELECT 列名
    FROM 表名
    [WHERE 条件]   # 条件查询
    [LIMIT N][ OFFSET M]  # 设置查询记录条数,以及开始查询的位置
    # eg
    # 查询全部数据
    select * from 表名
    # 条件查询 查询id大于10的八条记录
    select * from 表名 where id > 10 limit 8 
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    1. 查询语句中可以使用一个或者多个表,表之间使用逗号, 分割,并使用WHERE语句来设定查询条件。
    2. 可以在 WHERE 子句中指定任何条件。
    3. 可以使用 AND 或者 OR 指定一个或多个条件。
    4. WHERE 子句也可以运用于 SQL 的 DELETE 或者 UPDATE 命令。
    5. WHERE 子句类似于程序语言中的 if 条件,根据 MySQL 表中的字段值来读取指定的数据。
    操作符描述实例
    = 等号,检测两个值是否相等,如果相等返回true (A = B) 返回false。
    <>, != 不等于,检测两个值是否相等,如果不相等返回true (A != B) 返回 true。
    > 大于号,检测左边的值是否大于右边的值, 如果左边的值大于右边的值返回true (A > B) 返回false。
    < 小于号,检测左边的值是否小于右边的值, 如果左边的值小于右边的值返回true (A < B) 返回 true。
    >= 大于等于号,检测左边的值是否大于或等于右边的值, 如果左边的值大于或等于右边的值返回true (A >= B) 返回false。
    <= 小于等于号,检测左边的值是否小于或等于右边的值, 如果左边的值小于或等于右边的值返回true (A <= B) 返回 true。
    • 更新数据
    UPDATE table_name SET field1=new-value1, field2=new-value2
    [WHERE Clause]   # 根据条件修改数据
    
    • 1
    • 2
    1. 可以同时更新一个或多个字段。
    2. 可以在 WHERE 子句中指定任何条件。
    3. 可以在一个单独表中同时更新数据。

    2.3.4 like模糊查询

    LIKE 子句中使用百分号 %字符来表示任意字符,类似于UNIX或正则表达式中的星号 *。

    如果没有使用百分号 %, LIKE 子句与等号 = 的效果是一样的。

    SELECT * from tbl  WHERE author LIKE '%COM';
    
    • 1
    1. 可以在 WHERE 子句中指定任何条件。
    2. 可以在 WHERE 子句中使用LIKE子句。
    3. 可以使用LIKE子句代替等号 =。
      LIKE 通常与 % 一同使用,类似于一个元字符的搜索。
    4. 可以使用 AND 或者 OR 指定一个或多个条件。
    5. 可以在 DELETE 或 UPDATE 命令中使用 WHERE…LIKE 子句来指定条件。

    2.3.5 UNION 操作符

    UNION 操作符用于连接两个以上的 SELECT 语句的结果组合到一个结果集合中。多个 SELECT 语句会删除重复的数据。

    SELECT expression1, expression2, ... expression_n  # 数据列
    FROM tables  # 查询的表
    [WHERE conditions]   # 条件
    UNION [ALL | DISTINCT]   # all 返回所有数据包括重复数据,distinct相反
    SELECT expression1, expression2, ... expression_n
    FROM tables
    [WHERE conditions];
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2.3.6 order by排序

    SELECT field1, field2,...fieldN FROM table_name1, table_name2...
    ORDER BY field1 [ASC [DESC][默认 ASC]], [field2...] [ASC [DESC][默认 ASC]]
    
    # asc 升序 desc 降序,默认排序为升序
    
    #eg
    SELECT * from tbl ORDER BY submission_date ASC;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1. 可以使用任何字段来作为排序的条件,从而返回排序后的查询结果。
    2. 可以设定多个字段来排序。
    3. 可以使用 ASC 或 DESC 关键字来设置查询结果是按升序或降序排列。 默认情况下,它是按升序排列。
    4. 可以添加 WHERE…LIKE 子句来设置条件。

    2.3.7 group by分组

    GROUP BY 语句根据一个或多个列对结果集进行分组。

    在分组的列上我们可以使用 COUNT, SUM, AVG,等函数。

    SELECT column_name, function(column_name)
    FROM table_name
    WHERE column_name operator value
    GROUP BY column_name;
    
    #eg
     SELECT name, COUNT(*) FROM   employee_tbl GROUP BY name;
    # having一般于group by 一起使用,用来对分组后的集合进行操作
     SELECT name, COUNT(*) FROM   employee_tbl GROUP BY name having age >30;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    使用 WITH ROLLUP
    WITH ROLLUP 可以实现在分组统计数据基础上再进行相同的统计(SUM,AVG,COUNT…)。

    例如我们将以上的数据表按名字进行分组,再统计每个人登录的次数:

    mysql> SELECT name, SUM(signin) as signin_count FROM  employee_tbl GROUP BY name WITH ROLLUP;
    +--------+--------------+
    | name   | signin_count |
    +--------+--------------+
    | 小丽 |            2 |
    | 小明 |            7 |
    | 小王 |            7 |
    | NULL   |           16 |
    +--------+--------------+
    4 rows in set (0.00 sec)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    其中记录 NULL 表示所有人的登录次数。

    我们可以使用 coalesce 来设置一个可以取代 NUll 的名称,coalesce 语法:

    select coalesce(a,b,c);
    # 参数说明:如果a==null,则选择b;如果b==null,则选择c;如果a!=null,则选择a;如果a b c 都为null ,则返回为null(没意义)。
    
    • 1
    • 2
    mysql> SELECT coalesce(name, '总数'), SUM(signin) as signin_count FROM  employee_tbl GROUP BY name WITH ROLLUP;
    +--------------------------+--------------+
    | coalesce(name, '总数') | signin_count |
    +--------------------------+--------------+
    | 小丽                   |            2 |
    | 小明                   |            7 |
    | 小王                   |            7 |
    | 总数                   |           16 |
    +--------------------------+--------------+
    4 rows in set (0.01 sec)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2.3.8 join连接

    使用 MySQL 的 JOIN 在两个或多个表中查询数据。

    1. INNER JOIN(内连接,或等值连接):获取两个表中字段匹配关系的记录。
    2. LEFT JOIN(左连接):获取左表所有记录,即使右表没有对应匹配的记录。
    3. RIGHT JOIN(右连接): 与 LEFT JOIN 相反,用于获取右表所有记录,即使左表没有对应匹配的记录。
    mysql> use RUNOOB;
    Database changed
    mysql> SELECT * FROM tcount_tbl;
    +---------------+--------------+
    | runoob_author | runoob_count |
    +---------------+--------------+
    | 菜鸟教程  | 10           |
    | RUNOOB.COM    | 20           |
    | Google        | 22           |
    +---------------+--------------+
    3 rows in set (0.01 sec)
     
    mysql> SELECT * from runoob_tbl;
    +-----------+---------------+---------------+-----------------+
    | runoob_id | runoob_title  | runoob_author | submission_date |
    +-----------+---------------+---------------+-----------------+
    | 1         | 学习 PHP    | 菜鸟教程  | 2017-04-12      |
    | 2         | 学习 MySQL  | 菜鸟教程  | 2017-04-12      |
    | 3         | 学习 Java   | RUNOOB.COM    | 2015-05-01      |
    | 4         | 学习 Python | RUNOOB.COM    | 2016-03-06      |
    | 5         | 学习 C      | FK            | 2017-04-05      |
    +-----------+---------------+---------------+-----------------+
    5 rows in set (0.01 sec)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    mysql> SELECT a.runoob_id, a.runoob_author, b.runoob_count FROM runoob_tbl a INNER JOIN tcount_tbl b ON a.runoob_author = b.runoob_author;
    +-------------+-----------------+----------------+
    | a.runoob_id | a.runoob_author | b.runoob_count |
    +-------------+-----------------+----------------+
    | 1           | 菜鸟教程    | 10             |
    | 2           | 菜鸟教程    | 10             |
    | 3           | RUNOOB.COM      | 20             |
    | 4           | RUNOOB.COM      | 20             |
    +-------------+-----------------+----------------+
    4 rows in set (0.00 sec)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    mysql> SELECT a.runoob_id, a.runoob_author, b.runoob_count FROM runoob_tbl a, tcount_tbl b WHERE a.runoob_author = b.runoob_author;
    +-------------+-----------------+----------------+
    | a.runoob_id | a.runoob_author | b.runoob_count |
    +-------------+-----------------+----------------+
    | 1           | 菜鸟教程    | 10             |
    | 2           | 菜鸟教程    | 10             |
    | 3           | RUNOOB.COM      | 20             |
    | 4           | RUNOOB.COM      | 20             |
    +-------------+-----------------+----------------+
    4 rows in set (0.01 sec)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    mysql> SELECT a.runoob_id, a.runoob_author, b.runoob_count FROM runoob_tbl a LEFT JOIN tcount_tbl b ON a.runoob_author = b.runoob_author;
    +-------------+-----------------+----------------+
    | a.runoob_id | a.runoob_author | b.runoob_count |
    +-------------+-----------------+----------------+
    | 1           | 菜鸟教程    | 10             |
    | 2           | 菜鸟教程    | 10             |
    | 3           | RUNOOB.COM      | 20             |
    | 4           | RUNOOB.COM      | 20             |
    | 5           | FK              | NULL           |
    +-------------+-----------------+----------------+
    5 rows in set (0.01 sec)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    mysql> SELECT a.runoob_id, a.runoob_author, b.runoob_count FROM runoob_tbl a RIGHT JOIN tcount_tbl b ON a.runoob_author = b.runoob_author;
    +-------------+-----------------+----------------+
    | a.runoob_id | a.runoob_author | b.runoob_count |
    +-------------+-----------------+----------------+
    | 1           | 菜鸟教程    | 10             |
    | 2           | 菜鸟教程    | 10             |
    | 3           | RUNOOB.COM      | 20             |
    | 4           | RUNOOB.COM      | 20             |
    | NULL        | NULL            | 22             |
    +-------------+-----------------+----------------+
    5 rows in set (0.01 sec)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2.3.9 null处理

    IS NULL: 当列的值是 NULL,此运算符返回 true。
    IS NOT NULL: 当列的值不为 NULL, 运算符返回 true。
    <=>: 比较操作符(不同于 = 运算符),当比较的的两个值相等或者都为 NULL 时返回 true。
    关于 NULL 的条件比较运算是比较特殊的。你不能使用 = NULL 或 != NULL 在列中查找 NULL 值 。

    在 MySQL 中,NULL 值与任何其它值的比较(即使是 NULL)永远返回 NULL,即 NULL = NULL 返回 NULL 。

    MySQL 中处理 NULL 使用 IS NULL 和 IS NOT NULL 运算符。

    select * , columnName1+ifnull(columnName2,0) from tableName;
    
    • 1

    2.3.10 mysql正则表达式

    MySQL 同样也支持其他正则表达式的匹配, MySQL中使用 REGEXP 操作符来进行正则表达式匹配。

    模式描述
    ^匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 '\n' 或 '\r' 之后的位置。
    $匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 '\n' 或 '\r' 之前的位置。
    .匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用像 '[.\n]' 的模式。
    [...]字符集合。匹配所包含的任意一个字符。例如, '[abc]' 可以匹配 "plain" 中的 'a'。
    [^...]负值字符集合。匹配未包含的任意字符。例如, '[^abc]' 可以匹配 "plain" 中的'p'。
    p1|p2|p3匹配 p1 或 p2 或 p3。例如,'z|food' 能匹配 "z" 或 "food"。'(z|f)ood' 则匹配 "zood" 或 "food"。
    *匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。
    +匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。
    {n}n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。
    {n,m}m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。
    #查找name字段中以'st'为开头的所有数据:
    mysql> SELECT name FROM person_tbl WHERE name REGEXP '^st';
    # 查找name字段中以'ok'为结尾的所有数据:
    mysql> SELECT name FROM person_tbl WHERE name REGEXP 'ok$';
    #查找name字段中包含'mar'字符串的所有数据:
    mysql> SELECT name FROM person_tbl WHERE name REGEXP 'mar';
    # 查找name字段中以元音字符开头或以'ok'字符串结尾的所有数据:
    mysql> SELECT name FROM person_tbl WHERE name REGEXP '^[aeiou]|ok$';
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2.3.10 mysql事务

    MySQL 事务主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中,你删除一个人员,你既需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务!
    在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务。
    事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行。
    事务用来管理 insert,update,delete 语句
    一般来说,事务是必须满足4个条件(ACID)::原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。

    原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。

    一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。

    隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。

    持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
    事务控制语句:
    BEGIN 或 START TRANSACTION 显式地开启一个事务;

    COMMIT 也可以使用 COMMIT WORK,不过二者是等价的。COMMIT 会提交事务,并使已对数据库进行的所有修改成为永久性的;

    ROLLBACK 也可以使用 ROLLBACK WORK,不过二者是等价的。回滚会结束用户的事务,并撤销正在进行的所有未提交的修改;

    SAVEPOINT identifier,SAVEPOINT 允许在事务中创建一个保存点,一个事务中可以有多个 SAVEPOINT;

    RELEASE SAVEPOINT identifier 删除一个事务的保存点,当没有指定的保存点时,执行该语句会抛出一个异常;

    ROLLBACK TO identifier 把事务回滚到标记点;

    SET TRANSACTION 用来设置事务的隔离级别。InnoDB 存储引擎提供事务的隔离级别有READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ 和 SERIALIZABLE。

    MYSQL 事务处理主要有两种方法:
    1、用 BEGIN, ROLLBACK, COMMIT来实现

    BEGIN 开始一个事务
    ROLLBACK 事务回滚
    COMMIT 事务确认
    2、直接用 SET 来改变 MySQL 的自动提交模式:

    SET AUTOCOMMIT=0 禁止自动提交
    SET AUTOCOMMIT=1 开启自动提交

    mysql> use RUNOOB;
    Database changed
    mysql> CREATE TABLE runoob_transaction_test( id int(5)) engine=innodb;  # 创建数据表
    Query OK, 0 rows affected (0.04 sec)
     
    mysql> select * from runoob_transaction_test;
    Empty set (0.01 sec)
     
    mysql> begin;  # 开始事务
    Query OK, 0 rows affected (0.00 sec)
     
    mysql> insert into runoob_transaction_test value(5);
    Query OK, 1 rows affected (0.01 sec)
     
    mysql> insert into runoob_transaction_test value(6);
    Query OK, 1 rows affected (0.00 sec)
     
    mysql> commit; # 提交事务
    Query OK, 0 rows affected (0.01 sec)
     
    mysql>  select * from runoob_transaction_test;
    +------+
    | id   |
    +------+
    | 5    |
    | 6    |
    +------+
    2 rows in set (0.01 sec)
     
    mysql> begin;    # 开始事务
    Query OK, 0 rows affected (0.00 sec)
     
    mysql>  insert into runoob_transaction_test values(7);
    Query OK, 1 rows affected (0.00 sec)
     
    mysql> rollback;   # 回滚
    Query OK, 0 rows affected (0.00 sec)
     
    mysql>   select * from runoob_transaction_test;   # 因为回滚所以数据没有插入
    +------+
    | id   |
    +------+
    | 5    |
    | 6    |
    +------+
    2 rows in set (0.01 sec)
     
    mysql>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    2.3.10 mysql索引

    MySQL 索引是一种数据结构,用于加快数据库查询的速度和性能。MySQL 索引的建立对于 MySQL 的高效运行是很重要的,索引可以大大提高 MySQL 的检索速度。

    索引分单列索引和组合索引:

    • 单列索引,即一个索引只包含单个列,一个表可以有多个单列索引。
    • 组合索引,即一个索引包含多个列。
      创建索引时,你需要确保该索引是应用在 SQL 查询语句的条件(一般作为 WHERE 子句的条件)。

    实际上,索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录。

    索引虽然能够提高查询性能,但也需要注意以下几点:

    索引需要占用额外的存储空间。
    对表进行插入、更新和删除操作时,索引需要维护,可能会影响性能。
    过多或不合理的索引可能会导致性能下降,因此需要谨慎选择和规划索引。

    普通索引

    创建索引
    使用 CREATE INDEX 语句可以创建普通索引。

    普通索引是最常见的索引类型,用于加速对表中数据的查询。

    # index_name: 指定要创建的索引的名称。索引名称在表中必须是唯一的。
    CREATE INDEX index_name
    ON table_name (column1 [ASC|DESC], column2 [ASC|DESC], ...);
    #指定要索引的表列名。你可以指定一个或多个列作为索引的组合。这些列的数据类型通常是数值、文本或日期。
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    我们可以在创建表的时候,你可以在 CREATE TABLE 语句中直接指定索引,以创建表和索引的组合。
    删除索引的语法
    我们可以使用 DROP INDEX 语句来删除索引。

    DROP INDEX index_name ON table_name;
    
    
    • 1
    • 2

    唯一索引
    在 MySQL 中,你可以使用 CREATE UNIQUE INDEX 语句来创建唯一索引。

    唯一索引确保索引中的值是唯一的,不允许有重复值。

    CREATE UNIQUE INDEX index_name
    ON table_name (column1 [ASC|DESC], column2 [ASC|DESC], ...);
    
    
    • 1
    • 2
    • 3

    有四种方式来添加数据表的索引:

    ALTER TABLE tbl_name ADD PRIMARY KEY (column_list): 该语句添加一个主键,这意味着索引值必须是唯一的,且不能为NULL。
    ALTER TABLE tbl_name ADD UNIQUE index_name (column_list): 这条语句创建索引的值必须是唯一的(除了NULL外,NULL可能会出现多次)。
    ALTER TABLE tbl_name ADD INDEX index_name (column_list): 添加普通索引,索引值可出现多次。
    ALTER TABLE tbl_name ADD FULLTEXT index_name (column_list):该语句指定了索引为 FULLTEXT ,用于全文索引。

    mysql> ALTER TABLE testalter_tbl MODIFY i INT NOT NULL;
    mysql> ALTER TABLE testalter_tbl ADD PRIMARY KEY (i);
    
    mysql> ALTER TABLE testalter_tbl DROP PRIMARY KEY;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    显示索引信息
    你可以使用 SHOW INDEX 命令来列出表中的相关的索引信息。

    可以通过添加 \G 来格式化输出信息。

    SHOW INDEX 语句::

    mysql> SHOW INDEX FROM table_name\G
    ........
    
    
    • 1
    • 2
    • 3

    三、临时表

    MySQL 临时表在我们需要保存一些临时数据时是非常有用的。临时表只在当前连接可见,当关闭连接时,Mysql会自动删除表并释放所有空间。

    • 创建临时表
    CREATE TEMPORARY TABLE SalesSummary (
        product_name VARCHAR(50) NOT NULL, total_sales DECIMAL(12,2) NOT NULL DEFAULT 0.00
        , avg_unit_price DECIMAL(7,2) NOT NULL DEFAULT 0.00 , total_units_sold INT UNSIGNED NOT NULL DEFAULT 0
    );
    
    • 1
    • 2
    • 3
    • 4
    • 删除临时表
    DROP TABLE SalesSummary;
    
    • 1

    四、mysql序列

    MySQL 序列是一组整数:1, 2, 3, …,由于一张数据表只能有一个字段自增主键, 如果你想实现其他字段也实现自动增加,就可以使用MySQL序列来实现。

    1. 使用自增组件
      MySQL 中最简单使用序列的方法就是使用 MySQL AUTO_INCREMENT 来定义序列。
    mysql> CREATE TABLE insect
        -> (
        -> id INT UNSIGNED NOT NULL AUTO_INCREMENT,
        -> PRIMARY KEY (id),
        -> name VARCHAR(30) NOT NULL, # type of insect
        -> date DATE NOT NULL, # date collected
        -> origin VARCHAR(30) NOT NULL # where collected
    );
    Query OK, 0 rows affected (0.02 sec)
    mysql> INSERT INTO insect (id,name,date,origin) VALUES
        -> (NULL,'housefly','2001-09-10','kitchen'),
        -> (NULL,'millipede','2001-09-10','driveway'),
        -> (NULL,'grasshopper','2001-09-10','front yard');
    Query OK, 3 rows affected (0.02 sec)
    Records: 3  Duplicates: 0  Warnings: 0
    mysql> SELECT * FROM insect ORDER BY id;
    +----+-------------+------------+------------+
    | id | name        | date       | origin     |
    +----+-------------+------------+------------+
    |  1 | housefly    | 2001-09-10 | kitchen    |
    |  2 | millipede   | 2001-09-10 | driveway   |
    |  3 | grasshopper | 2001-09-10 | front yard |
    +----+-------------+------------+------------+
    3 rows in set (0.00 sec)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    在MySQL的客户端中你可以使用 SQL中的LAST_INSERT_ID( ) 函数来获取最后的插入表中的自增列的值。
    如果你删除了数据表中的多条记录,并希望对剩下数据的AUTO_INCREMENT列进行重新排列,那么你可以通过删除自增的列,然后重新添加来实现。 不过该操作要非常小心,如果在删除的同时又有新记录添加,有可能会出现数据混乱。

    mysql> CREATE TABLE insect
        -> (
        -> id INT UNSIGNED NOT NULL AUTO_INCREMENT,
        -> PRIMARY KEY (id),
        -> name VARCHAR(30) NOT NULL, 
        -> date DATE NOT NULL,
        -> origin VARCHAR(30) NOT NULL
    )engine=innodb auto_increment=100 charset=utf8;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    五、重复数据处理

    MySQL 数据表中可能存在重复的记录,有些情况我们允许重复数据的存在,但有时候我们也需要删除这些重复的数据。
    防止表中出现重复数据
    你可以在 MySQL 数据表中设置指定的字段为 PRIMARY KEY(主键) 或者 UNIQUE(唯一) 索引来保证数据的唯一性。
    让我们尝试一个实例:下表中无索引及主键,所以该表允许出现多条重复记录。

    CREATE TABLE person_tbl
    (
        first_name CHAR(20),
        last_name CHAR(20),
        sex CHAR(10)
    );
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    如果我们设置了唯一索引,那么在插入重复数据时,SQL 语句将无法执行成功,并抛出错。

    INSERT IGNORE INTO 与 INSERT INTO 的区别就是 INSERT IGNORE INTO 会忽略数据库中已经存在的数据,如果数据库没有数据,就插入新的数据,如果有数据的话就跳过这条数据。这样就可以保留数据库中已经存在数据,达到在间隙中插入数据的目的。

    以下实例使用了 INSERT IGNORE INTO,执行后不会出错,也不会向数据表中插入重复数据:

    mysql> INSERT IGNORE INTO person_tbl (last_name, first_name)
        -> VALUES( 'Jay', 'Thomas');
    Query OK, 1 row affected (0.00 sec)
    mysql> INSERT IGNORE INTO person_tbl (last_name, first_name)
        -> VALUES( 'Jay', 'Thomas');
    Query OK, 0 rows affected (0.00 sec)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    而 REPLACE INTO 如果存在 primary 或 unique 相同的记录,则先删除掉。再插入新记录。
    另一种设置数据的唯一性方法是添加一个 UNIQUE 索引,如下所示:

    CREATE TABLE person_tbl
    (
       first_name CHAR(20) NOT NULL,
       last_name CHAR(20) NOT NULL,
       sex CHAR(10),
       UNIQUE (last_name, first_name)
    );
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    以下我们将统计表中 first_name 和 last_name的重复记录数:

    mysql> SELECT COUNT(*) as repetitions, last_name, first_name
        -> FROM person_tbl
        -> GROUP BY last_name, first_name
        -> HAVING repetitions > 1;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    过滤重复数据
    如果你需要读取不重复的数据可以在 SELECT 语句中使用 DISTINCT 关键字来过滤重复数据。

    mysql> SELECT DISTINCT last_name, first_name
        -> FROM person_tbl;
    mysql> SELECT last_name, first_name
        -> FROM person_tbl
        -> GROUP BY (last_name, first_name);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    mysql> CREATE TABLE tmp SELECT last_name, first_name, sex FROM person_tbl  GROUP BY (last_name, first_name, sex);
    mysql> DROP TABLE person_tbl;
    mysql> ALTER TABLE tmp RENAME TO person_tbl;
    
    
    • 1
    • 2
    • 3
    • 4

    六、sql注入

    SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。

    我们永远不要信任用户的输入,我们必须认定用户输入的数据都是不安全的,我们都需要对用户输入的数据进行过滤处理。

  • 相关阅读:
    Spring Boot中如何定义多套不同环境配置?
    Kubernetes概述架构与工作流程简述
    python的类成员和实例成员
    Web前端一套全部清晰 ① 学习路线
    JAVA毕设项目社交的健身网课平台服务器端(java+VUE+Mybatis+Maven+Mysql)
    VINS-Fusion-GNSS松耦合原理
    Vulnhub靶机:CEREAL_ 1
    怎么压缩视频?最新压缩技巧大分享
    Qt应用开发(基础篇)——输入对话框 QInputDialog
    猿创征文|vue3+ts封装table组件并注册发布
  • 原文地址:https://blog.csdn.net/weixin_45915647/article/details/133693897