MYSQL手册阅读读书笔记

前言

 SQL以前学得马马虎虎。算是基本记得它们的原理,但是好久不写还是会经常写错。特别是遇到SQL Server与MYSQL与标准SQL都不兼容的情况下,还要去查不同的手册,查不同的语法。所以决定用BLOG的形式重述一下基本的语句结构,以后没事常看看。

       常见的语法标记,"[]"代表可选项,“|”代表多选一,"{}"代表强制选择的一组之一。

一、MYSQL的一些技术参数。

       MYSQL使用C++写成,拥有多种语言API。它的基本默认存储引擎以前是MYISAM,现在是InnoDB,共支持八种引擎。是使用B树的磁盘表。MYISAM是ISAM的升级版,比较倾向于小的数据库工程,对于一般的查询支持非常的快。但是因为它不支持事务,不支持行级锁,所以渐渐被支持事务安全的InnoDB引擎所取代。InnoDB支持的细粒度锁专门为ACID事务提供支持,特别适合大规模数据库的最高性能。

      MYSQL理论上支持所有的标准SQL、聚合函数、左右外连接、DML、DDL、DCL与ODBC。

      MYSQL的服务器是MYSQLD。

二、一些具体的值得注意的地方。

     1 关于约束,SQL语法的约束有很多种,比如NOT NULL、PRIMARY KEY、等等,都相当于一个可以直接加进Col名后面的约束,可以直接加,公式大概是:表名(Col 约束,Col 约束,Col 约束);

     2 关于括号, 凡是涉及多个Col连接的,都要使用"()"把Col包起来,比如

        insert into 表名 (Col,Col)

                          values(v,v);

     3 多余的对象要和表名的位置对称。如上。

     4 关于表的各种关键字权限:

            (1) 比较神奇的是,select关键字可以对表达式求值 ,例如select 1 +1 ;可以得到2。

            (2) 可以用create routine、alter routine之类的关键字来创建和更改程序,用execute来执行。

            (3)增加账户的两种方法,一是直接插入user表,另一种就是如下

                    GRANT ALL PRIVILEGES ON *.* TO 'monty'@'localhost' IDENTIFIED BY '123456' WITH GRANT OPTION;(注意这个grant to结构,必须用root权限登录)。目前MySQL支持八种特权,如果全部都grant了,就相当于root了。

      5 提到用户的地方,最好使用 用户名@ip地址 的形式。

三、关于查询优化

     1 你的许可设置得越复杂,所需要的开销就越大。可以用benchmark(count,expresion)的形式来进行基准测试,找到有问题的表达式。

     2 可以用explain语法来对select语句进行分析,它将解释select语句如何被执行。提醒我们要设置索引之类的东西(设置索引是提高查询速度的第一思路,MYSQL中所有的列类型都可以被索引,包括BLOB)。它的结果是一张表。

     3 有时候MYSQL会把连接强制置为Straight Join。

     4 MYSQL对MYISAM表进行表级锁,对BDB进行页级锁,对于InnoDB进行行级锁。有意思的是,MYSQL不会出现表死锁的情况,因为它会采取一次获取所有锁的策略。

     5 多数的数据库将行数据域索引文件保存在一起,但是MYSQL为了适应现代操作系统,特地把它们分开摆放。

四、如何设计数据库?

使数据尽可能地小,使用尽可能地小的类型、尽可能地使用Not NULL(为什么?)、使用尽可能小的索引、使用变长列。

五、关于MYSQL中的索引。

       索引的目的是什么?不是每次都查询每一条记录的整条,而是直接读索引列来找到特定匹配值!这样可以只把索引取到内存中,增加效率。

       创建索引的SQL语句。

       CREATE TABLE test (

id INT NOT NULL,

last_name CHAR(30) NOT NULL,

first_name CHAR(30) NOT NULL,

PRIMARY KEY (id),

INDEX NAME(last_name,first_name)/*把索引当作约束来写*/

);

       可以为一列做索引,也可以为多列做索引,最多位15列做索引。

六、MYSQL的语言结构

     1 字符串,MYSQL中''与‘是一个意思。

     2 MYSQL中有一个 b ‘0101111’类型的位字段值类型。可以用这样的语句实现:

        CREATE TABLE t (b BIT(8));/*八位字段值*/

     1与2说明的是MYSQL的文字值,与下面的列类型不同。

     3 有意思的是,可以用'`'(反勾号)来将关键字作为标示符存入数据库中,这意味着我们可以用“select”来作为表名或者数据库名!!但是,不可以用标示符做函数名。

        如:CREATE TABLE `select`(a INT);/*不需要指定主键和其他约束,居然也可以有表!*/

     4 关于大小写敏感性,操作系统的大小写敏感性决定数据库名和表名的大小写敏感性。Unix是大小写敏感的,Windows是大小写不敏感的。

     5 用户变量,每个客户端可以拥有自己独立的用户变量,只有本客户端可以看到和使用,可以把值从一个语句传递到另一个语句。

      可以用 set @var1 := exp, @var2 = exp ;//可以赋给用户变量整数、实数、字符串和NULL。

      例如:

SET @t1 = 0, @t2 = 2, @t3 = 0;

SELECT @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3;

      有意思的是,因为用户变量往往在发送到客户端以后才开始计算结果(而且你并不知道实际上的执行顺序),所以在一个语句的一部分设置一个变量,并在语句的另一部分中使用它们并一定能得到自己想要的结果。要避免这种情况,就要在之前的地方提前声明变量并给它赋值。这样可以保证这个赋值操作起码可以先执行。

     6 从用户变量引申出去,可以用

        set GLOBAL(@@global) var_name来设置全局变量;

        set SESSION (@@session) var_name来设置会话(或Local)变量。

     7 注释方法

        #字符到行尾

        -- 字符到行尾

        /**/包夹住注释

     8 嵌入式SQL可能引发一个问题,例如a ()可以是一个表定义,去掉这个空格,就可能变成一个函数调用。

七、列类型。

    分为

    1 数值型类型(不同长度的整数、浮点数)。

       数值类型用M来表示宽度,它代表着一定意义上的精度范围。用D表示位数。

       假设不考虑符号性。至少有BIT、TINYINT=BOOL、SMALLINT、MEDIUMINT、INT=INTEGER、BIGINT、FLOAT[(M,D)](4字节)、DOUBLE[(M,D)](8字节)、DECIMAL=NUMERIC(M,D)(必须知道确切精度,比如货币,实际上Numeric在MYSQL中并不被支持,是其他数据库引擎定义的,映射到Decimal上面)。

    2 日期与时间类型。

       分为

       DATE 纯粹的日期

       DATETIME 日期和时间

       TIMESTAMP 格式上与DATETIME几乎一样,但是它专门设计出来为INSERT和UPDATE操作进行时间戳记录。它有一种专有的特性,就是可以自动更新。

       TIME 单独的时间。

       YEAR 单独的年份。

      关于设置时间戳:

      可以选择将时间戳设置为一个缺省的默认值,或者当前值。

CREATE TABLE t2 (a TIMESTAMP);

CACHE TABLE t3 (a TIMESTAMP DEFAULT 0, b TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);

INSERT INTO t2 VALUES(NOW());

    3 字符串(字符)类型。

       char(M)  定长char序列,如果指定了长度,不足的部分也会用空格补足,但检索时空格会被去掉。

      CREATE TABLE binaryc (c BINARY(3));

      INSERT INTO binaryc VALUES ('a');

      SELECT c = 'a', c = 'a\0\0' FROM binaryc;

      返回结果为 0 和 1。 0x00在转义成字符以后即为\0。

       char = char(1)

       binary(M) 保存二进制字节字符串,长度不是按照字符数而是按照字节数。没有字符集,所以也就没有响应的校对规则。插入时自动补全0x00像空格一样,而且在选择和比较时都不会删去。

       varchar(M) 不定长,不会用空格补足。但是需要一个或者多余的字节存储字段的长度。

       varbinary(M) 保存二进制字节字符串

       tinytext text列

       blob 二进制大对象,可视为足够大的varbinary列

       text 可视为足够大的varchar列

       blob与text在保存或检索时不删除尾部空格。

       mediumblob

       mediumtext

       longblob

       longtext

       enum 字符串,和我们常见的枚举类型一样。但是在定义表结构的时候,就已经设定了可选的枚举值。插入错误的枚举值会存入空值。

       set 字符串集合,有点像枚举值,但是可以使用复合的成员作组合。

       如set(‘a’,‘b’) not null

       的值可以有

       ‘’       

‘a’

        ‘b’

‘a,b’

        set

       DROP TABLE IF EXISTS myset;

       CREATE TABLE myset (col SET ('a', 'b','c', 'd') );

       INSERT INTO myset VALUES ('a,d'), ('d,a'), ('d,a,d');

       SELECT * FROM myset;       

       最后的出来的结果,都是根据字母排过序的(‘a,d’);

       这些成对出现的类型,都有着相应的最大长度和存储需求。

      有意思的是char在被取出数据库的时候,会自动去掉所有空格,不管是插入时故意留进去的,还是系统自动增加进去的,所以要保存空格,一定要使用varchar。

      例如:

      DROP TABLE IF EXISTS vc;

      CREATE TABLE vc (v VARCHAR(4), c CHAR(4));

      INSERT INTO vc VALUES("ab  ","ab  ");

      SELECT CONCAT(v,'+'), CONCAT(c,'+') FROM vc;

      这会返回 “ab  +”与“ab+”。

      因为char类型与varchar类型的对比规则是padspace是不考虑任何尾部空格。

      DROP TABLE IF EXISTS NAMES;

      CREATE TABLE NAMES (myname CHAR(10), yourname VARCHAR(10));

      INSERT INTO NAMES VALUES ("monty    ","monty    ");

      SELECT myname = "monty",yourname = "monty   " FROM NAMES;

      不管这里面多少个空格,返回结果都能找到两个1。

七、MYSQL中的函数与操作符

      在select语句的order by子句或having 子句或者在select、delete、update语句的set和where子句中都要遇到表达式。可以用文本值、column值、null值、函数、操作符来书写表达式。一般来说,带有null的表达式总会返回null。如果可以函数调用时,函数名和括号之间千万不要有空格。

     1 操作符。

        :=

        ||,OR,XOR

        &&,AND

NOT

        BETWEEN,CASE,WHEN,THEN,ELSE

        =,<=>(NULL SAFE EQUAL), >=,>,<=,<,<>,!=,is like,regexp,in,

        |

       &

        <<,>>

        -,+

        *,/,DIV,%,MOD

        ^

        -(一元减号),~(一元比特反转)

       !

       BINARY,COLLATE

(1)大于号

       SELECT 1>"6x";--返回0

      SELECT 7>"6x";--返回1

        --值得注意的是,字符串和数字是可以相互转换自由比较的。

        (2) 等于号

          SELECT 0='0';

         (3)安全等于号

           SELECT 1<=>'1', NULL <=> NULL,1 <=> NULL;

           --非安全的等于号,第二个查询结果会返回NULL,而安全的等于号第二个查询结果会返回1。注意NULL不等于0。

          (4)检验布尔值。用is来做检验是否为某个布尔值。从以下查询可以清楚地看到一一对应的关系。

           SELECT 1 IS TRUE,0 IS FALSE , NULL IS UNKNOWN;

            
           (5)expr between min and max
                   若表达式属于两者这一,则返回1,否则返回0。
                   例如
SELECT 3  BETWEEN 2 AND 4;
会返回1。
           (6)COALESCE(value,...)返回第一个非NULL值,如果全部为NULL则返回NULL。
                   例如
SELECT COALESCE(NULL,1,2);
                  会返回1。

猜你喜欢

转载自cppbomb.iteye.com/blog/1594670