美文网首页
跟着大宇学MySQL

跟着大宇学MySQL

作者: 小大宇 | 来源:发表于2021-07-22 17:37 被阅读0次

    表的基本操作

    表结构变化之前要备份,因为数据是无法恢复的。
    不是每张表都是需要主键的!
    有外键关联的两张表必须使用相同的存储引擎。
    自增属性默认从1开始。如果你插入的id是5,那么下次自增的id属性就是6。
    主键,不允许为空。它能唯一的标识表中的一条记录
    外键要么为空,要么等于另外一个表的已经存在的主键。
    PRIMARY KEY 与 QNIQUE的区别:UNIQUE允许数据为空,而PRIMARY KEY不允许为空。

    数据类型

    DATETIME格式的时间,按实际输入的数据格式。
    TIMESTAMP格式的时间,是按照UTC世界标准时间格式存储的。存储时,先把当地时区的时间换算成世界标准时间,取出的时候,再把世界标准时间换算成当地时区的时间。 当地时间 <=====> 世界标准时间

    char是固定长度的字符串,字符串长度由定义的时候指明。如果插入的字符串没有达到定义的长度,那么就用空格补充。在取出的时候,会去掉尾部的所有空格。

    varchar是可变长类型的字符串。字符串长度是其实际插入的字符串长度。varchar会保留住插入的字符串的空格。在取出数据的时候,也会把空格一并取出。

    varchar比char节省空间,但是效率上比char要低。
    如果一个字符串经常被修改,并且每次修改的长度都可能不一样,那么如果用varchar可能会造成‘行迁移’现象。这种情况下用char比较好。

    行迁移:如果一块数据磁盘空间无法保存某个数据时(比如以前是1k,现在update到2k,而当前块的空闲空间不足1k),则会将新的数据保存到另外一个新的块里,然后在以前的块保存一个新位置的地址连接。

    TEXT类型是可变长类型。一般用于文章内容、评论等较大文件的信息。

    BLOB字段存储的是二进制数据。而TEXT存储的是非二进制字符串。

    如何选择数据类型

    整数和浮点数
    不需要小数的情况,使用整数。需要小数的情况使用浮点数。
    精度要求较高的时候,使用DOUBLE而不是FLOAT。

    浮点类型有两种:单精度浮点类型FLOAT,双精度浮点类型DOUBLE。它们的区别仅在存储范围不同。分别占4,8字节。

    定点类型有一种:DECIMAL。用法与FLOAT、DOUBLE一样。只不过它的占位是 M+2 字节。

    浮点数与定点数
    浮点数的优点在于能表示更大的数据范围,缺点是浮点数的计算容易产生误差。(有四舍五入)
    浮点数 FLOAT(M,D)因为是非标准SQL定义,在数据库迁移的时候容易产生误差。

    定点数因为内部使用的是字符串的形式存储的,所以适用于精度较高的场景,比如金额。另外,如果要进行数值比较,最好使用DECIMAL类型。

    算术运算

    除以的是0,那么返回的是NULL
    与NULL运算的结果是NULL

    几乎与'='运算一致,区别是 '<=>' 能用来对NULL进行判断,若两者均为NULL,则返回1,否则返回0。
    <>不等于运算符,或者是 !=
    语法: A IS NULL 、 B IS NOT NULL ,ISNULL(C)

    SELECT
      sex,
      name,
      sex IS NULL,
      name IS NOT NULL,
      ISNULL(sex)
    FROM t_char
    
    image.png

    函数

    CONCAT_WS(X,S1,S2,S3),返回效果如 S1XS2XS3 。如果S1、S2、S3有NULL,那么会自动被忽略。

    SELECT 
        CONCAT('%','mysql','%'), 
        CONCAT_WS('-','1996','05','19'),
        CONCAT('%',NULL,'%'),
        CONCAT_WS('-','1996','05',NULL,'19')
    ;
    
    image.png

    条件函数
    IF(expr,V1,V2) 功能与Java的三目运算符一样,如果expr为真,返回V1,否则为V2
    IFNULL(V1,V2); 如果V1是NULL,返回V2。V1不是NULL,返回V1。

    SELECT 
        IF(1>0,2,3),
        IF(1<0,2,3),
        IFNULL(NULL,4),
        IFNULL(5,6)
    ;
    
    image.png

    CASE WHEN

         SELECT 
            CASE 1>0
                WHEN 1 THEN 'true'
                WHEN 0 THEN 'FALSE'
                ELSE        'MORE'
            END AS result;
    
    image.png

    CASE WHEN 另外一种变法。
    如果没有表达式,那么将会顺序执行下面的WHEN语句,直到第一个为条件满足,返回后面的值。若没有符合的,则返回ELSE后面的值。

    CASE 
                     WHEN v1 THEN r1
                     WHEN v2 THEN r2 
                    ...
                     ELSE       rn
              END
    
     SELECT 
            CASE 
                WHEN 1>2 THEN 'A'
                WHEN 1<2 THEN 'B'
                WHEN 1<3 THEN 'C'
                ELSE          'D'
             END AS RESULT
    
    image.png
    SELECT 
    USER_ACCOUNT,
    (CASE 
      WHEN SEX = 1 THEN '男' 
      WHEN SEX = 2 THEN '女' 
      ELSE '未知'
    END )sex
    FROM m_user u 
    
    SELECT CHAR_LENGTH('xiao da yu') AS length;   //10
    
    有空为空
    SELECT CONCAT('xiao ','da ','yu') AS myName; //xiao da yu
    
    免疫空
    SELECT CONCAT_WS("-", 'xiao', NULL, 'da', 'yu') AS myName; //xiao-da-yu
    

    国际化金额函数。

    SELECT FORMAT("123456.789",2);    
    SELECT FORMAT(123456.789,2); 
    
    image.png image.png

    字符串替换。把给定字符串从【start,end】替换为给定字符串。
    比如下面的例子中,从1到4,就是"XIAO"替换为"xiao"。

    SELECT INSERT("XIAO da yu",1,4,"xiao") AS myName//xiao da yu
    

    字符串定位。某个字符串首次出现的位置。有null运算返回null。

    SELECT LOCATE("da",'xiao da yu') AS startIndex;
    

    有个字符串叫:"从头开始学mysql",需求是这个字符串改为"从头开始学MySQL"。
    首先要定位到"mysql"的开始位置,然后计算出"mysql"的长度。最后用"MySQL"替换"mysql"。

    SELECT INSERT ('从头开始学mysql',
    LOCATE('mysql','从头开始学mysql'),CHAR_LENGTH('mysql'),'MySQL')
    AS blogName
    

    大小写

    SELECT LCASE('MYSQL') AS '小写' , UCASE('mysql') AS '大写'
    

    返回前X位,后X位。

    SELECT LEFT('mysql',2) AS '前两位' , RIGHT('mysql',2) AS '后两位'
    
    image.png

    去掉首位空格。LTRIM去掉左边空格,RTRIM去掉右边空格,TRIM去掉两边空格。

    SELECT 
    LTRIM('   mysql'),RTRIM('mysql    '), TRIM('  mysql  ')
    

    替换

    SELECT REPLACE('Mysql','sql','SQL') AS result
    
    image.png

    反转

    SELECT REVERSE('LQSyM') AS result
    

    截取

    SELECT SUBSTRING("MySQL", 1, 3) AS result //MyS
    

    连接分组下所有属性值 (NULL值会被忽略)


    image.png
    SELECT classId, GROUP_CONCAT(name) FROM t_student 
    GROUP BY classId
    
    image.png

    MAX MIN SUM AVG ABS

    提取日期时间表达式中

    SELECT 
    now(),
    DATE(now()),
    YEAR(now()),
    MONTH(now()),
    DAY(now()),
    TIME(now())
    
    image.png

    以当前时间为基准,增加时间,减少时间

    SELECT 
    now(),
    ADDDATE(now(), INTERVAL 1 second) '1秒后',
    ADDDATE(now(), INTERVAL 1 minute) '1分后',
    ADDDATE(now(), INTERVAL 1 hour)   '1小时后',
    ADDDATE(now(), INTERVAL 1 day)    '1天后',
     
    SUBDATE(now(), INTERVAL 2 day)    '2天前'
    
    image.png

    基于上述,来弄一个基本需求。获取前三个小时到当前时间的所有记录。


    image.png
    SELECT  t.* , now() AS '当前时间' FROM T_TIME_TEST t
    WHERE t.TIME_STR BETWEEN SUBDATE(now(), INTERVAL 3 HOUR) AND now()
    
    image.png

    时间格式化

    SELECT 
    DATE_FORMAT(now(),'%Y-%m-%d-%r') AS '全',
    DATE_FORMAT(now(),'%Y-%m-%d %H:%i:%s') '年月日 时分秒'
    
    image.png

    查询

    DISTINCT控制的重复是DISTINCT后面所有字段!

    升序与降序,究竟是哪个方向?
    从第一条记录开始,往下比较指定的字段。如果越来越高,说明就是升序。
    从第一条记录开始,往下比较指定的字段。越来越低,说明就是降序。
    如果使用UNION ALL 可以连接多条查询语句,并将它们的结果集组合起来。
    不加ALL的效果:返回结果中删除重复的记录。
    将查询结果插入到表中

    INSERT INTO t_person(name,address)
    SELECT accountName , accountAddress FROM t_info;
    

    -- articleId 默认值为 5
    INSERT INTO t_tag(name,articleId) values ("a",null);
    INSERT INTO t_tag(name) values ("a");
    指明null则插入null,否则用默认值5

    索引

    索引是一个单独的、存储在磁盘上的数据库结构,它们包含着对数据库表里所有记录的引用指针。使用索引用于快速找出在某个或者多个列中有一特定值的行。对相关列使用索引是提高查询操作速度的最佳途径。
    索引的优点:
    (1)创建唯一索引,可以限制表的某列数据唯一,效果就像为那列数据加上了UNIQUE关键字一样。
    (2)加快查询速度,这是创建索引最核心的原因。从4秒钟的查询时间变成了几毫秒,简直不可思议。
    (3)在使用分组和排序子句进行数据查询的时候,显著减少查询中分组与排序的时间。

    索引的缺点:
    占空间,难维护。因为索引是存储在物理磁盘上的,所以占磁盘。在数据库中数据修改的时候,索引也会关联变动,降低了数据的维护速度,即维护索引较为耗时。

    索引数量并非越多越好,因为索引占磁盘空间。且表中数据更改时,索引也会更新。就像目录一样。

    对经常用于查询的字段设计索引。索引列尽可能少,避免添加不必要的字段。

    数据量小的表不要用索引。就像正文没一两页,还去查目录一样。

    不同值较多的列上建立索引。相反,如果列上值较少,比如“男、女”,加了索引只会降低数据更新速度。

    在频繁进行排序与分组的表上建立索引。如果排序列有多个,可以建立组合索引。

    当唯一性是某种数据的特征时,可以指定唯一索引。

    尽量使用短索引。对字符串类型的字段进行索引,如果可能应该指定一个前缀长度。比如在CHAR(255)的列,如果在前10个或者30个字符,多数值是唯一的,则不需要对整个列进行索引。

    分类
    普通索引:MySQL的基本索引,索引列可以插入空值与重复值。

    唯一索引:索引列的值必须唯一,但允许为空。效果就像为列加上了UNIQUE关键字。
    主键是一种特殊的唯一索引,不允许为空值。

    单列索引:一个索引只包含一个列。

    组合索引:在多个字段组合上创建的索引,只有在查询条件中使用了这些字段的最左边字段时,索引才会被使用。这个原则称为"最左前缀"。

    type字段类型为varchar,而SQL中是数字类型,所以不走索引。因此,大家也注意一下。需要把 2 修改为 字符串2:"2"。

    视图

    视图是一个虚拟的表,它是把数据库中的一张或者多张表中的一些数据列,拼接起来的虚拟的表。
    视图的好处:看到的就是需要的。另外,当视图表的某张数据来源表的表结构变化,只要那列数据不变,即使真实表的位置发生变化,也不影响视图。

    视图就是已经编译好的SQL。它把多张表里面的一些数据抽取出来,拼接成一张新的虚拟的表,这张虚拟的表里只有我们最想要的数据,这样就很好的保护了基本表中的其它数据。

    对视图增加或者删除记录,实际上是对基本表增加或者删除记录。
    如果往视图中插入的数据不包括基本表中非空的数据,那么插入失败。

    (1)视图是已经编译好的SQL语句,是基于SQL语句的结果集的可视化表。
    
    (2)视图是逻辑上的存在,它是查看数据的一种办法,它不占磁盘。而表占物理磁盘。
    
    (3)视图的建立和删除只影响视图本身,不影响对应的基本表。
    
    (4)视图可以防止用户接触数据表,因为视图是虚拟的表,用户不知道基本表的表结构。
    
    UPDATE stu_teac_info set stuIdCard = 320103 WHERE stuName = '大宇';
    

    执行完毕后,查看视图,视图中的相关数据已经被修改了。 再查看基本表,基本表中的数据也被修改了。

    相关文章

      网友评论

          本文标题:跟着大宇学MySQL

          本文链接:https://www.haomeiwen.com/subject/nwxymltx.html