MySql-Note

RDBMS 即關(guān)系數(shù)據(jù)庫管理系統(tǒng)(Relational Database Management System)的特點:

  • 數(shù)據(jù)以表格的形式出現(xiàn)
  • 每行為各種記錄名稱
  • 每列為記錄名稱所對應(yīng)的數(shù)據(jù)域
  • 許多的行和列組成一張表單
  • 若干的表單組成database

RDBMS 術(shù)語

  • 數(shù)據(jù)庫: 數(shù)據(jù)庫是一些關(guān)聯(lián)表的集合敞咧。
  • 數(shù)據(jù)表: 表是數(shù)據(jù)的矩陣。在一個數(shù)據(jù)庫中的表看起來像一個簡單的電子表格缚窿。
  • 列: 一列(數(shù)據(jù)元素) 包含了相同類型的數(shù)據(jù), 例如郵政編碼的數(shù)據(jù)调鲸。
  • 行:一行(=元組盛杰,或記錄)是一組相關(guān)的數(shù)據(jù),例如一條用戶訂閱的數(shù)據(jù)藐石。
  • 冗余:存儲兩倍數(shù)據(jù)即供,冗余降低了性能,但提高了數(shù)據(jù)的安全性于微。
  • 主鍵:主鍵是唯一的逗嫡。一個數(shù)據(jù)表中只能包含一個主鍵。你可以使用主鍵來查詢數(shù)據(jù)株依。
  • 外鍵:外鍵用于關(guān)聯(lián)兩個表驱证。
  • 復(fù)合鍵:復(fù)合鍵(組合鍵)將多個列作為一個索引鍵,一般用于復(fù)合索引恋腕。
  • 索引:使用索引可快速訪問數(shù)據(jù)庫表中的特定信息抹锄。索引是對數(shù)據(jù)庫表中一列或多列的+ 值進(jìn)行排序的一種結(jié)構(gòu)。類似于書籍的目錄荠藤。
  • 參照完整性: 參照的完整性要求關(guān)系中不允許引用不存在的實體伙单。與實體完整性是關(guān)系+ 模型必須滿足的完整性約束條件,目的是保證數(shù)據(jù)的一致性

創(chuàng)建數(shù)據(jù)庫

CREATE DATABASE 數(shù)據(jù)庫名; //create DATABASE RUNOOB;

刪除數(shù)據(jù)庫

drop database <數(shù)據(jù)庫名>; //drop database RUNOOB;

選擇數(shù)據(jù)庫

use RUNOOB <數(shù)據(jù)庫名>; //use RUNOOB;Database changed

數(shù)據(jù)類型

數(shù)值類型

包括嚴(yán)格數(shù)值數(shù)據(jù)類型(INTEGER哈肖、SMALLINT吻育、DECIMAL和NUMERIC)西剥,以及近似數(shù)值數(shù)據(jù)類型(FLOAT诡右、REAL和DOUBLE PRECISION)输瓜。

關(guān)鍵字INT是INTEGER的同義詞纵潦,關(guān)鍵字DEC是DECIMAL的同義詞溺健。

BIT數(shù)據(jù)類型保存位字段值丘喻,并且支持MyISAM膝但、MEMORY荒辕、InnoDB和BDB表总寻。

作為SQL標(biāo)準(zhǔn)的擴(kuò)展器罐,MySQL也支持整數(shù)類型TINYINT、MEDIUMINT和BIGINT渐行。

NUMERIC.png

日期和時間類型

表示時間值的日期和時間類型為DATETIME轰坊、DATE铸董、TIMESTAMP、TIME和YEAR肴沫。

每個時間類型有一個有效值范圍和一個"零"值粟害,當(dāng)指定不合法的MySQL不能表示的值時使用"零"值。

date.png

字符串類型

字符串類型指CHAR颤芬、VARCHAR悲幅、BINARY、VARBINARY站蝠、BLOB汰具、TEXT、ENUM和SET菱魔。該節(jié)描述了這些類型如何工作以及如何在查詢中使用這些類型

CHAR 和 VARCHAR 類型類似留荔,但它們保存和檢索的方式不同。它們的最大長度和是否尾部空格被保留等方面也不同澜倦。在存儲或檢索過程中不進(jìn)行大小寫轉(zhuǎn)換聚蝶。

BINARY 和 VARBINARY 類似于 CHAR 和 VARCHAR,不同的是它們包含二進(jìn)制字符串而不要非二進(jìn)制字符串藻治。也就是說碘勉,它們包含字節(jié)字符串而不是字符字符串。這說明它們沒有字符集桩卵,并且排序和比較基于列值字節(jié)的數(shù)值值恰聘。

BLOB 是一個二進(jìn)制大對象,可以容納可變數(shù)量的數(shù)據(jù)吸占。有 4 種 BLOB 類型:TINYBLOB、BLOB凿宾、MEDIUMBLOB 和 LONGBLOB矾屯。它們區(qū)別在于可容納存儲范圍不同。

有 4 種 TEXT 類型:TINYTEXT初厚、TEXT件蚕、MEDIUMTEXT 和 LONGTEXT。對應(yīng)的這 4 種 BLOB 類型产禾,可存儲的最大長度不同排作,可根據(jù)實際情況選擇。

string.png

創(chuàng)建數(shù)據(jù)表

建MySQL數(shù)據(jù)表需要以下信息:
表名
表字段名
定義每個表字段

CREATE TABLE table_name (column_name column_type);

 CREATE TABLE IF NOT EXISTS `root_tbl`(
  `root_id` INT UNSIGNED AUTO_INCREMENT,
  `root_title` VARCHAR(100) NOT NULL,
  `root_author` VARCHAR(40) NOT NULL,
  `submission_date` DATE,
   PRIMARY KEY ( `root_id` )
 )ENGINE=InnoDB DEFAULT CHARSET=utf8;

如果你不想字段為 NULL 可以設(shè)置字段的屬性為 NOT NULL亚情, 在操作數(shù)據(jù)庫時如果輸入該字段的數(shù)據(jù)為NULL 妄痪,就會報錯。
AUTO_INCREMENT定義列為自增的屬性楞件,一般用于主鍵衫生,數(shù)值會自動加1裳瘪。
PRIMARY KEY關(guān)鍵字用于定義列為主鍵。 您可以使用多列來定義主鍵罪针,列間以逗號分隔彭羹。
ENGINE 設(shè)置存儲引擎,CHARSET 設(shè)置編碼泪酱。

創(chuàng)建主鍵為ID的表

 CREATE TABLE FOO (ID INT IDENTITY, BAR VARCHAR(64));
MySQL 字段屬性應(yīng)該盡量設(shè)置為 NOT NULL

除非你有一個很特別的原因去使用 NULL 值派殷,你應(yīng)該總是讓你的字段保持 NOT NULL。這看起來好像有點爭議墓阀,請往下看毡惜。

1、首先岂津,我們要搞清楚空值 "" 和 NULL 的概念:

1)空值是不占用空間的
2)MySQL中的NULL其實是占用空間的
所謂的 NULL 就是什么都沒有虱黄,連 \0 都沒有,\0 在字符串中是結(jié)束符吮成,但是在物理內(nèi)存是占空間的橱乱,等于一個字節(jié),而 NULL 就是連這一個字節(jié)都沒有粱甫。

2泳叠、其次,在數(shù)據(jù)庫里是嚴(yán)格區(qū)分的茶宵,任何數(shù)跟 NULL 進(jìn)行運算都是 NULL, 判斷值是否等于 NULL危纫,不能簡單用 =,而要用 IS NULL關(guān)鍵字乌庶。

3种蝶、數(shù)據(jù)庫的字段 col1 設(shè)為 NOT NULL, 僅僅說明該字段不能為 NULL, 也就是說只有在:

INSERT INTO table1(col1) VALUES(NULL);
這種情況下數(shù)據(jù)庫會報錯,而:

INSERT INTO table1(col1) VALUES('');
不會報錯瞒大。

(如果字段是自增ID螃征,第一句不會報錯,這不能說明是可以為NULL,而是 數(shù)據(jù)庫系統(tǒng)會根據(jù)ID設(shè)的缺省值填充透敌,或者如果是自增字段就自動加一等缺省操作盯滚。)

4、含有空值的列很難進(jìn)行查詢優(yōu)化酗电,而且對表索引時不會存儲 NULL 值的魄藕,所以如果索引的字段可以為 NULL,索引的效率會下降很多撵术。因為它們使得索引背率、索引的統(tǒng)計信息以及比較運算更加復(fù)雜。你應(yīng)該用 0、一個特殊的值或者一個空串代替空值退渗。

5移稳、聯(lián)表查詢的時候,例如 LEFT JOIN table2会油,若沒有記錄个粱,則查找出的 table2 字段都是 null。假如 table2 有些字段本身可以是 null翻翩,那么除非把 table2 中 not null 的字段查出來都许,否則就難以區(qū)分到底是沒有關(guān)聯(lián)記錄還是其他情況。

刪除數(shù)據(jù)表

1嫂冻、drop table table_name : 刪除表全部數(shù)據(jù)和表結(jié)構(gòu)胶征,立刻釋放磁盤空間,不管是 Innodb 和 MyISAM;

 DROP TABLE student;

2桨仿、truncate table table_name : 刪除表全部數(shù)據(jù)睛低,保留表結(jié)構(gòu),立刻釋放磁盤空間 服傍,不管是 Innodb 和 MyISAM;

 TRUNCATE TABLE student;

3钱雷、delete from table_name : 刪除表全部數(shù)據(jù),表結(jié)構(gòu)不變吹零,對于 MyISAM 會立刻釋放磁盤空間罩抗,InnoDB 不會釋放磁盤空間;

  DELETE FROM student;

4、delete from table_name where xxx : 帶條件的刪除灿椅,表結(jié)構(gòu)不變套蒂,不管是 innodb 還是 MyISAM 都不會釋放磁盤空間;

 DELETE FROM student WHERE T_name = "張三";

5、delete 操作以后茫蛹,使用 optimize table table_name 會立刻釋放磁盤空間操刀,不管是 innodb 還是 myisam;

DELETE FROM student WHERE T_name = "張三";
OPTIMIZE TABLE student;

6、delete from 表以后雖然未釋放磁盤空間婴洼,但是下次插入數(shù)據(jù)的時候馍刮,仍然可以使用這部分空間。

插入數(shù)據(jù)

MySQL數(shù)據(jù)表插入數(shù)據(jù)通用的 INSERT INTO SQL語法

INSERT INTO table_name ( field1, field2,...fieldN )
                   VALUES
                   ( value1, value2,...valueN );
//Example                   
INSERT INTO `user_relation` (
    `user_id`,
    `target_user_id`,
    `in_dtm`,
    `in_user`
)
VALUES
    (
    #{user_id},
    #{target_user_id},
    #{in_dtm},
    #{user_id}
    );                   

查詢數(shù)據(jù)

MySQL數(shù)據(jù)庫中查詢數(shù)據(jù)通用的 SELECT 語法:

SELECT column_name,column_name
 FROM table_name
[WHERE Clause]
[LIMIT N][ OFFSET M]
  • SELECT * : 返回所有記錄
  • LIMIT N : 返回 N 條記錄
  • OFFSET M : 跳過 M 條記錄, 默認(rèn) M=0, 單獨使用似乎不起作用
  • LIMIT N,M : 相當(dāng)于 LIMIT M OFFSET N , 從第 N 條記錄開始, 返回 M 條記錄
       SELECT
            im.id
        FROM    
        im
        WHERE im.status = '1'
        AND im.type = 0

      SELECT * FROM table LIMIT 5,10
Example

/websites 表名 NAME alexa url country 字段/

SELECT * FROM websites;                      /* 查詢表所有數(shù)據(jù) */

SELECT NAME FROM websites;                   /* 查詢表字段數(shù)據(jù) */

SELECT * FROM websites where name = "廣西";   /* 查詢表字段下條件數(shù)據(jù) */

SELECT * from websites where name like "_o%"; /* 模糊查詢表下數(shù)據(jù) */

SELECT * FROM websites where id BETWEEN "1" AND "5";    /* 查詢表下字段范圍數(shù)據(jù) */

SELECT * FROM websites WHERE name in ("廣西","百度");    /* 查詢表字段下固定條件數(shù)據(jù) */

SELECT DISTINCT country FROM Websites;                  /* 查詢?nèi)ブ刂?*/

SELECT * FROM Websites WHERE country = "CN" AND alexa > 50;  /*查詢表下范圍條件數(shù)據(jù)*/

SELECT * FROM Websites WHERE country = "USA" OR country="sh"; /* 查詢表下條件不同值 */

SELECT * FROM Websites ORDER BY alexa;                      /* 查詢表下值排序結(jié)果 */

SELECT * FROM Websites ORDER BY alexa DESC;                 /* 查詢表下排序結(jié)果降序 */

SELECT * FROM Websites LIMIT 2;      /* 查詢表下范圍數(shù)據(jù) */

SELECT name as zzz from websites;    /*別名查詢表下數(shù)據(jù)*/

Join連接查詢

join.jpg

####### 要理解各種JOIN首先要理解笛卡爾積窃蹋。笛卡爾積就是將A表的每一條記錄與B表的每一條記錄強(qiáng)行拼在一起。所以静稻,如果A表有n條記錄警没,B表有m條記錄,笛卡爾積產(chǎn)生的結(jié)果就會產(chǎn)生n*m條記錄振湾。下面的例子,t_blog有10條記錄续语,t_type有5條記錄,所有他們倆的笛卡爾積有50條記錄怖糊。有五種產(chǎn)生笛卡爾積的方式如下饮亏。

  • 內(nèi)連接:INNER JOIN

內(nèi)連接INNER JOIN是最常用的連接操作百侧。從數(shù)學(xué)的角度講就是求兩個表的交集,從笛卡爾積的角度講就是從笛卡爾積中挑出ON子句條件成立的記錄。有INNER JOIN避咆,WHERE(等值連接)樊销,STRAIGHT_JOIN,JOIN(省略INNER)四種寫法。至于哪種好我會在MySQL的JOIN(二):優(yōu)化講述。示例如下积蔚。

 SELECT * FROM t_blog INNER JOIN t_type ON t_blog.typeId=t_type.id;
 SELECT * FROM t_blog,t_type WHERE t_blog.typeId=t_type.id;
 SELECT * FROM t_blog STRAIGHT_JOIN t_type ON t_blog.typeId=t_type.id; --注意STRIGHT_JOIN有個下劃線
 SELECT * FROM t_blog JOIN t_type ON t_blog.typeId=t_type.id;
+----+-------+--------+----+------+
| id | title | typeId | id | name |
+----+-------+--------+----+------+
|  1 | aaa   |      1 |  1 | C++  |
|  2 | bbb   |      2 |  2 | C    |
|  7 | ggg   |      2 |  2 | C    |
|  3 | ccc   |      3 |  3 | Java |
|  6 | fff   |      3 |  3 | Java |
|  4 | ddd   |      4 |  4 | C#   |
|  5 | eee   |      4 |  4 | C#   |
+----+-------+--------+----+------+
  • 左連接:LEFT JOIN
    左連接LEFT JOIN的含義就是求兩個表的交集外加左表剩下的數(shù)據(jù)意鲸。依舊從笛卡爾積的角度講,就是先從笛卡爾積中挑出ON子句條件成立的記錄尽爆,然后加上左表中剩余的記錄(見最后三條)怎顾。

      SELECT * FROM t_blog LEFT JOIN t_type ON t_blog.typeId=t_type.id;
      +----+-------+--------+------+------+
      | id | title | typeId | id   | name |
      +----+-------+--------+------+------+
      |  1 | aaa   |      1 |    1 | C++  |
      |  2 | bbb   |      2 |    2 | C    |
      |  7 | ggg   |      2 |    2 | C    |
      |  3 | ccc   |      3 |    3 | Java |
      |  6 | fff   |      3 |    3 | Java |
      |  4 | ddd   |      4 |    4 | C#   |
      |  5 | eee   |      4 |    4 | C#   |
      |  8 | hhh   |   NULL | NULL | NULL |
      |  9 | iii   |   NULL | NULL | NULL |
      | 10 | jjj   |   NULL | NULL | NULL |
      +----+-------+--------+------+------+
    
  • 右連接:RIGHT JOIN

    同理右連接RIGHT JOIN就是求兩個表的交集外加右表剩下的數(shù)據(jù)。再次從笛卡爾積的角度描述漱贱,右連接就是從笛卡爾積中挑出ON子句條件成立的記錄槐雾,然后加上右表中剩余的記錄(見最后一條)。

    SELECT * FROM t_blog RIGHT JOIN t_type ON t_blog.typeId=t_type.id;
    +------+-------+--------+----+------------+
    | id   | title | typeId | id | name       |
    +------+-------+--------+----+------------+
    |    1 | aaa   |      1 |  1 | C++        |
    |    2 | bbb   |      2 |  2 | C          |
    |    3 | ccc   |      3 |  3 | Java       |
    |    4 | ddd   |      4 |  4 | C#         |
    |    5 | eee   |      4 |  4 | C#         |
    |    6 | fff   |      3 |  3 | Java       |
    |    7 | ggg   |      2 |  2 | C          |
    | NULL | NULL  |   NULL |  5 | Javascript |
    +------+-------+--------+----+------------+ 
  • 外連接:OUTER JOIN

    外連接就是求兩個集合的并集饱亿。從笛卡爾積的角度講就是從笛卡爾積中挑出ON子句條件成立的記錄,然后加上左表中剩余的記錄,最后加上右表中剩余的記錄彪笼。另外MySQL不支持OUTER JOIN钻注,但是我們可以對左連接和右連接的結(jié)果做UNION操作來實現(xiàn)。

      SELECT * FROM t_blog LEFT JOIN t_type ON t_blog.typeId=t_type.id
      UNION
      SELECT * FROM t_blog RIGHT JOIN t_type ON t_blog.typeId=t_type.id;
      +------+-------+--------+------+------------+
      | id   | title | typeId | id   | name       |
      +------+-------+--------+------+------------+
      |    1 | aaa   |      1 |    1 | C++        |
      |    2 | bbb   |      2 |    2 | C          |
      |    7 | ggg   |      2 |    2 | C          |
      |    3 | ccc   |      3 |    3 | Java       |
      |    6 | fff   |      3 |    3 | Java       |
      |    4 | ddd   |      4 |    4 | C#         |
      |    5 | eee   |      4 |    4 | C#         |
      |    8 | hhh   |   NULL | NULL | NULL       |
      |    9 | iii   |   NULL | NULL | NULL       |
      |   10 | jjj   |   NULL | NULL | NULL       |
      | NULL | NULL  |   NULL |    5 | Javascript |
      +------+-------+--------+------+------------+
    
  • USING子句

    MySQL中連接SQL語句中配猫,ON子句的語法格式為:table1.column_name = table2.column_name幅恋。當(dāng)模式設(shè)計對聯(lián)接表的列采用了相同的命名樣式時,就可以使用 USING 語法來簡化 ON 語法泵肄,格式為:USING(column_name)捆交。
    所以,USING的功能相當(dāng)于ON腐巢,區(qū)別在于USING指定一個屬性名用于連接兩個表品追,而ON指定一個條件。另外冯丙,SELECT *時肉瓦,USING會去除USING指定的列,而ON不會胃惜。實例如下

      SELECT * FROM t_blog INNER JOIN t_type ON t_blog.typeId =t_type.id;
      +----+-------+--------+----+------+
      | id | title | typeId | id | name |
      +----+-------+--------+----+------+
      |  1 | aaa   |      1 |  1 | C++  |
      |  2 | bbb   |      2 |  2 | C    |
      |  7 | ggg   |      2 |  2 | C    |
      |  3 | ccc   |      3 |  3 | Java |
      |  6 | fff   |      3 |  3 | Java |
      |  4 | ddd   |      4 |  4 | C#   |
      |  5 | eee   |      4 |  4 | C#   |
      +----+-------+--------+----+------+
      
      SELECT * FROM t_blog INNER JOIN t_type USING(id); -- 應(yīng)為t_blog的typeId與t_type的id不同名泞莉,無法用Using,這里用id代替下船殉。
      +----+-------+--------+------------+
      | id | title | id | name       |
      +----+-------+--------+------------+
      |  1 | aaa   |      1 | C++        |
      |  2 | bbb   |      2 | C          |
      |  3 | ccc   |      3 | Java       |
      |  4 | ddd   |      4 | C#         |
      |  5 | eee   |      4 | Javascript |
      +----+-------+--------+------------+    
    
  • 自然連接:NATURE JOIN

    自然連接就是USING子句的簡化版鲫趁,它找出兩個表中相同的列作為連接條件進(jìn)行連接。有左自然連接利虫,右自然連接和普通自然連接之分挨厚。在t_blog和t_type示例中,兩個表相同的列是id列吼,所以會拿id作為連接條件幽崩。
    另外千萬分清下面三條語句的區(qū)別 。

    自然連接:SELECT * FROM t_blog NATURAL JOIN t_type;

    笛卡爾積:SELECT * FROM t_blog NATURA JOIN t_type;

    笛卡爾積:SELECT * FROM t_blog NATURE JOIN t_type;

    SELECT * FROM t_blog NATURAL JOIN t_type;
    SELECT t_blog.id,title,typeId,t_type.name FROM t_blog,t_type WHERE t_blog.id=t_type.id;
    SELECT t_blog.id,title,typeId,t_type.name FROM t_blog INNER JOIN t_type ON t_blog.id=t_type.id;
     SELECT t_blog.id,title,typeId,t_type.name FROM t_blog INNER JOIN t_type USING(id);

    +----+-------+--------+------------+
    | id | title | typeId | name       |
    +----+-------+--------+------------+
    |  1 | aaa   |      1 | C++        |
    |  2 | bbb   |      2 | C          |
    |  3 | ccc   |      3 | Java       |
    |  4 | ddd   |      4 | C#         |
    |  5 | eee   |      4 | Javascript |
    +----+-------+--------+------------+

    SELECT * FROM t_blog NATURAL LEFT JOIN t_type;
    SELECT t_blog.id,title,typeId,t_type.name FROM t_blog LEFT JOIN t_type ON t_blog.id=t_type.id;
    SELECT t_blog.id,title,typeId,t_type.name FROM t_blog LEFT JOIN t_type USING(id);

    +----+-------+--------+------------+
    | id | title | typeId | name       |
    +----+-------+--------+------------+
    |  1 | aaa   |      1 | C++        |
    |  2 | bbb   |      2 | C          |
    |  3 | ccc   |      3 | Java       |
    |  4 | ddd   |      4 | C#         |
    |  5 | eee   |      4 | Javascript |
    |  6 | fff   |      3 | NULL       |
    |  7 | ggg   |      2 | NULL       |
    |  8 | hhh   |   NULL | NULL       |
    |  9 | iii   |   NULL | NULL       |
    | 10 | jjj   |   NULL | NULL       |
    +----+-------+--------+------------+

    SELECT * FROM t_blog NATURAL RIGHT JOIN t_type;
    SELECT t_blog.id,title,typeId,t_type.name FROM t_blog RIGHT JOIN t_type ON t_blog.id=t_type.id;
    SELECT t_blog.id,title,typeId,t_type.name FROM t_blog RIGHT JOIN t_type USING(id);

    +----+------------+-------+--------+
    | id | name       | title | typeId |
    +----+------------+-------+--------+
    |  1 | C++        | aaa   |      1 |
    |  2 | C          | bbb   |      2 |
    |  3 | Java       | ccc   |      3 |
    |  4 | C#         | ddd   |      4 |
    |  5 | Javascript | eee   |      4 |
    +----+------------+-------+--------+

WHERE 子句

    SELECT field1, field2,...fieldN FROM table_name1, table_name2...
    [WHERE condition1 [AND [OR]] condition2.....    
  • 查詢語句中你可以使用一個或者多個表寞钥,表之間使用逗號, 分割慌申,并使用WHERE語句來設(shè)定查詢條件。
  • 可以在 WHERE 子句中指定任何條件理郑。
  • 可以使用 AND 或者 OR 指定一個或多個條件蹄溉。
  • WHERE 子句也可以運用于 SQL 的 DELETE 或者 UPDATE 命令。
  • WHERE 子句類似于程序語言中的 if 條件您炉,根據(jù) MySQL 表中的字段值來讀取指定的數(shù)據(jù)柒爵。

以下為操作符列表,可用于 WHERE 子句中赚爵。

下表中實例假定 A 為 10, B 為 20

where.png

UPDATE 更新

UPDATE table_name SET field1=new-value1, field2=new-value2
[WHERE Clause]
  • 可以同時更新一個或多個字段棉胀。
  • 可以在 WHERE 子句中指定任何條件法瑟。
  • 可以在一個單獨表中同時更新數(shù)據(jù)。

Example

        UPDATE 
            topic
        SET 
            is_deleted = #{is_deleted}, 
            edit_dtm = #{edit_dtm}, 
            edit_user = #{edit_dtm}
        WHERE
            user_id = #{user_id} 
        AND topic_id = #{topic_id}

LIKE 子句

SELECT field1, field2,...fieldN 
FROM table_name
WHERE field1 LIKE condition1 [AND [OR]] filed2 = 'somevalue'        
  • 可以在 WHERE 子句中指定任何條件唁奢。
  • 可以在 WHERE 子句中使用LIKE子句霎挟。
  • 可以使用LIKE子句代替等號 =。
  • LIKE 通常與 % 一同使用麻掸,類似于一個元字符的搜索酥夭。
  • 可以使用 AND 或者 OR 指定一個或多個條件。
  • 可以在 DELETE 或 UPDATE 命令中使用 WHERE...LIKE 子句來指定條件脊奋。
    '%a'     //以a結(jié)尾的數(shù)據(jù)
    'a%'     //以a開頭的數(shù)據(jù)
    '%a%'    //含有a的數(shù)據(jù)
    '_a_'    //三位且中間字母是a的
    '_a'     //兩位且結(jié)尾字母是a的
    'a_'     //兩位且開頭字母是a的       
    
    
    //查詢以 java 字段開頭的信息熬北。
    SELECT * FROM position WHERE name LIKE 'java%';
    
    //查詢包含 java 字段的信息。
    SELECT * FROM position WHERE name LIKE '%java%';
    
    //查詢以 java 字段結(jié)尾的信息诚隙。
    SELECT * FROM position WHERE name LIKE '%java';
  • %:表示任意 0 個或多個字符讶隐。可匹配任意類型和長度的字符最楷,有些情況下若是中文整份,請使用兩個百分號(%%)表示。
  • _:表示任意單個字符籽孙。匹配單個任意字符烈评,它常用來限制表達(dá)式的字符長度語句。
  • []:表示括號內(nèi)所列字符中的一個(類似正則表達(dá)式)犯建。指定一個字符讲冠、字符串或范圍,要求所匹配對象為它們中的任一個适瓦。
  • [^] :表示不在括號所列之內(nèi)的單個字符竿开。其取值和 [] 相同,但它要求所匹配對象為指定字符以外的任一個字符玻熙。
  • 查詢內(nèi)容包含通配符時,由于通配符的緣故否彩,導(dǎo)致我們查詢特殊字符 “%”、“_”嗦随、“[” 的語句無法正常實現(xiàn)列荔,而把特殊字符用 “[ ]” 括起便可正常查詢。

UNION 操作符

SELECT expression1, expression2, ... expression_n
FROM tables
[WHERE conditions]
UNION [ALL | DISTINCT]
SELECT expression1, expression2, ... expression_n
FROM tables
[WHERE conditions];

expression1, expression2, ... expression_n: 要檢索的列枚尼。

tables: 要檢索的數(shù)據(jù)表贴浙。

WHERE conditions: 可選, 檢索條件署恍。

DISTINCT: 可選崎溃,刪除結(jié)果集中重復(fù)的數(shù)據(jù)。默認(rèn)情況下 UNION 操作符已經(jīng)刪除了重復(fù)數(shù)據(jù)盯质,所以 DISTINCT 修飾符對結(jié)果沒啥影響袁串。

ALL: 可選概而,返回所有結(jié)果集,包含重復(fù)數(shù)據(jù)囱修。

Example

(SELECT a.item_a FROM list a where a.status = 1 and a.item_b = #{id})
        UNION
(SELECT b.item_b FROM list b where b.status = 1 and b.item_a = #{id} and b.bind_type = 1)

排序

MySQL 的 ORDER BY 子句來設(shè)定你想按哪個字段哪種方式來進(jìn)行排序到腥,再返回搜索結(jié)果

SELECT field1, field2,...fieldN FROM table_name1, table_name2...
ORDER BY field1 [ASC [DESC][默認(rèn) ASC]], [field2...] [ASC [DESC][默認(rèn) ASC]]
  • 可以使用任何字段來作為排序的條件,從而返回排序后的查詢結(jié)果蔚袍。
  • 可以設(shè)定多個字段來排序。
  • 可以使用 ASC 或 DESC 關(guān)鍵字來設(shè)置查詢結(jié)果是按升序或降序排列配名。 默認(rèn)情況下啤咽,它是按升序排列。
  • 可以添加 WHERE...LIKE 子句來設(shè)置條件渠脉。

Example

SELECT * from table ORDER BY date DESC  

NULL 值處理

MySQL 使用 SQL SELECT 命令及 WHERE 子句來讀取數(shù)據(jù)表中的數(shù)據(jù),但是當(dāng)提供的查詢條件字段為 NULL 時宇整,該命令可能就無法正常工作
關(guān)于 NULL 的條件比較運算是比較特殊的。你不能使用 = NULL 或 != NULL 在列中查找 NULL 值 芋膘。

在 MySQL 中鳞青,NULL 值與任何其它值的比較(即使是 NULL)永遠(yuǎn)返回 NULL,即 NULL = NULL 返回 NULL 为朋。

MySQL 中處理 NULL 使用 IS NULL 和 IS NOT NULL 運算符

  • IS NULL: 當(dāng)列的值是 NULL,此運算符返回 true臂拓。
  • IS NOT NULL: 當(dāng)列的值不為 NULL, 運算符返回 true。
  • <=>: 比較操作符(不同于 = 運算符)习寸,當(dāng)比較的的兩個值相等或者都為 NULL 時返回 true胶惰。
    SELECT * FROM `table`  WHERE title IS NOT NULL LIMIT 0,1000
    SELECT * FROM `table`  WHERE date <=> NULL LIMIT 0,1000

正則表達(dá)式

MySQL可以通過 LIKE ...% 來進(jìn)行模糊匹配
MySQL 同樣也支持其他正則表達(dá)式的匹配, MySQL中使用 REGEXP 操作符來進(jìn)行正則表達(dá)式匹配

REGEXP.png

查找name字段中以'st'為開頭的所有數(shù)據(jù):

SELECT name FROM person_tbl WHERE name REGEXP '^st';

查找name字段中以'ok'為結(jié)尾的所有數(shù)據(jù):

SELECT name FROM person_tbl WHERE name REGEXP 'ok$';

查找name字段中包含'mar'字符串的所有數(shù)據(jù):

SELECT name FROM person_tbl WHERE name REGEXP 'mar';

查找name字段中以元音字符開頭或以'ok'字符串結(jié)尾的所有數(shù)據(jù):

SELECT name FROM person_tbl WHERE name REGEXP '^[aeiou]|ok$';       

事務(wù)

MySQL 事務(wù)主要用于處理操作量大霞溪,復(fù)雜度高的數(shù)據(jù)孵滞。比如說,在人員管理系統(tǒng)中鸯匹,你刪除一個人員坊饶,你既需要刪除人員的基本資料,也要刪除和該人員相關(guān)的信息殴蓬,如信箱匿级,文章等等,這樣科雳,這些數(shù)據(jù)庫操作語句就構(gòu)成一個事務(wù)根蟹!

  • 在 MySQL 中只有使用了 Innodb 數(shù)據(jù)庫引擎的數(shù)據(jù)庫或表才支持事務(wù)。
  • 事務(wù)處理可以用來維護(hù)數(shù)據(jù)庫的完整性糟秘,保證成批的 SQL 語句要么全部執(zhí)行简逮,要么全部不執(zhí)行。
  • 事務(wù)用來管理 insert,update,delete 語句

一般來說尿赚,事務(wù)是必須滿足4個條件(ACID)::原子性(Atomicity散庶,或稱不可分割性)蕉堰、一致性(Consistency)、隔離性(Isolation悲龟,又稱獨立性)屋讶、持久性(Durability)。

  • 原子性:一個事務(wù)(transaction)中的所有操作须教,要么全部完成皿渗,要么全部不完成,不會結(jié)束在中間某個環(huán)節(jié)轻腺。事務(wù)在執(zhí)行過程中發(fā)生錯誤乐疆,會被回滾(Rollback)到事務(wù)開始前的狀態(tài),就像這個事務(wù)從來沒有執(zhí)行過一樣贬养。

  • 一致性:在事務(wù)開始之前和事務(wù)結(jié)束以后挤土,數(shù)據(jù)庫的完整性沒有被破壞。這表示寫入的資料必須完全符合所有的預(yù)設(shè)規(guī)則误算,這包含資料的精確度仰美、串聯(lián)性以及后續(xù)數(shù)據(jù)庫可以自發(fā)性地完成預(yù)定的工作。

  • 隔離性:數(shù)據(jù)庫允許多個并發(fā)事務(wù)同時對其數(shù)據(jù)進(jìn)行讀寫和修改的能力儿礼,隔離性可以防止多個事務(wù)并發(fā)執(zhí)行時由于交叉執(zhí)行而導(dǎo)致數(shù)據(jù)的不一致咖杂。事務(wù)隔離分為不同級別,包括讀未提交(Read uncommitted)蚊夫、讀提交(read committed)翰苫、可重復(fù)讀(repeatable read)和串行化(Serializable)。

  • 持久性:事務(wù)處理結(jié)束后这橙,對數(shù)據(jù)的修改就是永久的奏窑,即便系統(tǒng)故障也不會丟失。

在 MySQL 命令行的默認(rèn)設(shè)置下屈扎,事務(wù)都是自動提交的埃唯,即執(zhí)行 SQL 語句后就會馬上執(zhí)行 COMMIT 操作。因此要顯式地開啟一個事務(wù)務(wù)須使用命令 BEGIN 或 START TRANSACTION鹰晨,或者執(zhí)行命令 SET AUTOCOMMIT=0墨叛,用來禁止使用當(dāng)前會話的自動提交
事務(wù)控制語句:
  • BEGIN 或 START TRANSACTION 顯式地開啟一個事務(wù);

  • COMMIT 也可以使用 COMMIT WORK模蜡,不過二者是等價的漠趁。COMMIT 會提交事務(wù),并使已對數(shù)據(jù)庫進(jìn)行的所有修改成為永久性的忍疾;

  • ROLLBACK 也可以使用 ROLLBACK WORK闯传,不過二者是等價的÷倍剩回滾會結(jié)束用戶的事務(wù)甥绿,并撤銷正在進(jìn)行的所有未提交的修改字币;

  • SAVEPOINT identifier,SAVEPOINT 允許在事務(wù)中創(chuàng)建一個保存點共缕,一個事務(wù)中可以有多個 SAVEPOINT洗出;

  • RELEASE SAVEPOINT identifier 刪除一個事務(wù)的保存點,當(dāng)沒有指定的保存點時图谷,執(zhí)行該語句會拋出一個異常翩活;

  • ROLLBACK TO identifier 把事務(wù)回滾到標(biāo)記點;

  • SET TRANSACTION 用來設(shè)置事務(wù)的隔離級別便贵。InnoDB 存儲引擎提供事務(wù)的隔離級別有READ UNCOMMITTED隅茎、READ COMMITTED、REPEATABLE READ 和 SERIALIZABLE嫉沽。

MYSQL 事務(wù)處理主要有兩種方法:

1、用 BEGIN, ROLLBACK, COMMIT來實現(xiàn)

  • BEGIN 開始一個事務(wù)

  • ROLLBACK 事務(wù)回滾

  • COMMIT 事務(wù)確認(rèn)
    2俏竞、直接用 SET 來改變 MySQL 的自動提交模式:

  • SET AUTOCOMMIT=0 禁止自動提交

  • SET AUTOCOMMIT=1 開啟自動提交

ALTER命令

當(dāng)我們需要修改數(shù)據(jù)表名或者修改數(shù)據(jù)表字段時绸硕,就需要使用到MySQL ALTER命令。

刪除魂毁,添加或修改表字段

如下命令使用了 ALTER 命令及 DROP 子句來刪除以上創(chuàng)建表的 i 字段:

ALTER TABLE tab  DROP i;

如果數(shù)據(jù)表中只剩余一個字段則無法使用DROP來刪除字段玻佩。

MySQL 中使用 ADD 子句來向數(shù)據(jù)表中添加列,如下實例在表 table 中添加 i 字段席楚,并定義數(shù)據(jù)類型:

ALTER TABLE table ADD i INT;

如果你需要指定新增字段的位置咬崔,可以使用MySQL提供的關(guān)鍵字 FIRST (設(shè)定位第一列), AFTER 字段名(設(shè)定位于某個字段之后)烦秩。

ALTER TABLE testalter_tbl DROP i;
ALTER TABLE testalter_tbl ADD i INT FIRST;
ALTER TABLE testalter_tbl DROP i;
ALTER TABLE testalter_tbl ADD i INT AFTER c;
修改字段類型及名稱

如果需要修改字段類型及名稱, 你可以在ALTER命令中使用 MODIFY 或 CHANGE 子句 垮斯。

例如,把字段 c 的類型從 CHAR(1) 改為 CHAR(10)只祠,可以執(zhí)行以下命令:

ALTER TABLE table MODIFY c CHAR(10);

使用 CHANGE 子句, 語法有很大的不同兜蠕。 在 CHANGE 關(guān)鍵字之后,緊跟著的是你要修改的字段名抛寝,然后指定新字段名及類型熊杨。嘗試如下實例:

ALTER TABLE table CHANGE i j BIGINT;
ALTER TABLE table CHANGE j j INT;
ALTER TABLE 對 Null 值和默認(rèn)值的影響

當(dāng)你修改字段時,你可以指定是否包含值或者是否設(shè)置默認(rèn)值盗舰。

以下實例晶府,指定字段 j 為 NOT NULL 且默認(rèn)值為100

ALTER TABLE table  MODIFY j BIGINT NOT NULL DEFAULT 100;
修改字段默認(rèn)值

可以使用 ALTER 來修改字段的默認(rèn)值

ALTER TABLE table ALTER i SET DEFAULT 1000

修改表名

如果需要修改數(shù)據(jù)表的名稱,可以在 ALTER TABLE 語句中使用 RENAME 子句來實現(xiàn)钻趋。

嘗試以下實例將數(shù)據(jù)表 table 重命名為 user_table:

ALTER TABLE table RENAME TO user_table;

索引

MySQL索引的建立對于MySQL的高效運行是很重要的川陆,索引可以大大提高M(jìn)ySQL的檢索速度。

  • 創(chuàng)建索引時蛮位,你需要確保該索引是應(yīng)用在 SQL 查詢語句的條件(一般作為 WHERE 子句的條件)书劝。

  • 實際上进倍,索引也是一張表,該表保存了主鍵與索引字段购对,并指向?qū)嶓w表的記錄猾昆。

  • 上面都在說使用索引的好處,但過多的使用索引將會造成濫用骡苞。因此索引也會有它的缺點:雖然索引大大提高了查詢速度垂蜗,同時卻會降低更新表的速度,如對表進(jìn)行INSERT解幽、UPDATE和DELETE贴见。因為更新表時,MySQL不僅要保存數(shù)據(jù)躲株,還要保存一下索引文件片部。

  • 建立索引會占用磁盤空間的索引文件

普通索引

創(chuàng)建索引

這是最基本的索引,它沒有任何限制霜定。它有以下幾種創(chuàng)建方式:

CREATE INDEX indexName ON mytable(username(length)); 

如果是CHAR档悠,VARCHAR類型,length可以小于字段實際長度望浩;如果是BLOB和TEXT類型辖所,必須指定 length诉稍。

修改表結(jié)構(gòu)(添加索引)

ALTER table tableName ADD INDEX indexName(columnName)

創(chuàng)建表的時候直接指定

CREATE TABLE mytable(  
 
ID INT NOT NULL,   
 
username VARCHAR(16) NOT NULL,  
 
INDEX [indexName] (username(length))  
 
);  

刪除索引的語法

DROP INDEX [indexName] ON mytable;  

唯一索引

它與前面的普通索引類似捌臊,不同的就是:索引列的值必須唯一,但允許有空值希俩。如果是組合索引典挑,則列值的組合必須唯一酥宴。它有以下幾種創(chuàng)建方式:

創(chuàng)建索引

CREATE UNIQUE INDEX indexName ON mytable(username(length)) 

修改表結(jié)構(gòu)

ALTER table mytable ADD UNIQUE [indexName] (username(length))

創(chuàng)建表的時候直接指定
CREATE TABLE mytable(

ID INT NOT NULL,   
 
username VARCHAR(16) NOT NULL,  
 
UNIQUE [indexName] (username(length))  
 
);      

使用ALTER 命令添加和刪除索引

有四種方式來添加數(shù)據(jù)表的索引:

  • ALTER TABLE tbl_name ADD PRIMARY KEY (column_list): 該語句添加一個主鍵,這意味著索引值必須是唯一的您觉,且不能為NULL幅虑。

  • ALTER TABLE tbl_name ADD UNIQUE index_name (column_list): 這條語句創(chuàng)建索引的值必須是唯一的(除了NULL外,NULL可能會出現(xiàn)多次)顾犹。

  • ALTER TABLE tbl_name ADD INDEX index_name (column_list): 添加普通索引倒庵,索引值可出現(xiàn)多次。

  • ALTER TABLE tbl_name ADD FULLTEXT index_name (column_list):該語句指定了索引為 FULLTEXT 炫刷,用于全文索引擎宝。

      ALTER TABLE testalter_tbl ADD INDEX (c);
      ALTER TABLE testalter_tbl DROP INDEX c;
    

使用 ALTER 命令添加和刪除主鍵

主鍵只能作用于一個列上,添加主鍵索引時浑玛,你需要確保該主鍵默認(rèn)不為空(NOT NULL)绍申。實例如下:

ALTER TABLE testalter_tbl MODIFY i INT NOT NULL;
ALTER TABLE testalter_tbl ADD PRIMARY KEY (i);      

你也可以使用 ALTER 命令刪除主鍵:

ALTER TABLE testalter_tbl DROP PRIMARY KEY; 

顯示索引信息

SHOW INDEX FROM table_name; \G  

元數(shù)據(jù)

  • 查詢結(jié)果信息: SELECT, UPDATE 或 DELETE語句影響的記錄數(shù)。
  • 數(shù)據(jù)庫和數(shù)據(jù)表的信息: 包含了數(shù)據(jù)庫及數(shù)據(jù)表的結(jié)構(gòu)信息。
  • MySQL服務(wù)器信息: 包含了數(shù)據(jù)庫服務(wù)器的當(dāng)前狀態(tài)极阅,版本號等

獲取服務(wù)器元數(shù)據(jù)

Metadata.png

序列使用

MySQL 序列是一組整數(shù):1, 2, 3, ...胃碾,由于一張數(shù)據(jù)表只能有一個字段自增主鍵, 如果你想實現(xiàn)其他字段也實現(xiàn)自動增加筋搏,就可以使用MySQL序列來實現(xiàn)

使用 AUTO_INCREMENT
MySQL 中最簡單使用序列的方法就是使用 MySQL AUTO_INCREMENT 來定義列仆百。

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
);  

重置序列

如果你刪除了數(shù)據(jù)表中的多條記錄,并希望對剩下數(shù)據(jù)的AUTO_INCREMENT列進(jìn)行重新排列奔脐,那么你可以通過刪除自增的列俄周,然后重新添加來實現(xiàn)。 不過該操作要非常小心髓迎,如果在刪除的同時又有新記錄添加峦朗,有可能會出現(xiàn)數(shù)據(jù)混亂。操作如下所示:

ALTER TABLE insect DROP id;
ALTER TABLE insect ADD id INT UNSIGNED NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY (id);

設(shè)置序列的開始值

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;

或者你也可以在表創(chuàng)建成功后排龄,通過以下語句來實現(xiàn):

ALTER TABLE t AUTO_INCREMENT = 100;

處理重復(fù)數(shù)據(jù)

有些 MySQL 數(shù)據(jù)表中可能存在重復(fù)的記錄波势,有些情況我們允許重復(fù)數(shù)據(jù)的存在,但有時候我們也需要刪除這些重復(fù)的數(shù)據(jù)橄维。

防止表中出現(xiàn)重復(fù)數(shù)據(jù)

  • 可以在 MySQL 數(shù)據(jù)表中設(shè)置指定的字段為 PRIMARY KEY(主鍵) 或者 UNIQUE(唯一) 索引來保證數(shù)據(jù)的唯一性

讓我們嘗試一個實例:下表中無索引及主鍵尺铣,所以該表允許出現(xiàn)多條重復(fù)記錄。

CREATE TABLE person_tbl
(
    first_name CHAR(20),
    last_name CHAR(20),
    sex CHAR(10)
);

如果你想設(shè)置表中字段 first_name挣郭,last_name 數(shù)據(jù)不能重復(fù),你可以設(shè)置雙主鍵模式來設(shè)置數(shù)據(jù)的唯一性疗韵, 如果你設(shè)置了雙主鍵兑障,那么那個鍵的默認(rèn)值不能為 NULL,可設(shè)置為 NOT NULL蕉汪。如下所示:

CREATE TABLE person_tbl
(
   first_name CHAR(20) NOT NULL,
   last_name CHAR(20) NOT NULL,
   sex CHAR(10),
   PRIMARY KEY (last_name, first_name)
);

如果我們設(shè)置了唯一索引流译,那么在插入重復(fù)數(shù)據(jù)時,SQL 語句將無法執(zhí)行成功,并拋出錯者疤。

INSERT IGNORE INTO 與 INSERT INTO 的區(qū)別就是 INSERT IGNORE 會忽略數(shù)據(jù)庫中已經(jīng)存在的數(shù)據(jù)福澡,如果數(shù)據(jù)庫沒有數(shù)據(jù),就插入新的數(shù)據(jù)驹马,如果有數(shù)據(jù)的話就跳過這條數(shù)據(jù)革砸。這樣就可以保留數(shù)據(jù)庫中已經(jīng)存在數(shù)據(jù),達(dá)到在間隙中插入數(shù)據(jù)的目的糯累。

以下實例使用了 INSERT IGNORE INTO算利,執(zhí)行后不會出錯,也不會向數(shù)據(jù)表中插入重復(fù)數(shù)據(jù):

INSERT IGNORE INTO person_tbl (last_name, first_name) VALUES( 'Jay', 'Thomas');

INSERT IGNORE INTO person_tbl (last_name, first_name) VALUES( 'Jay', 'Thomas');

NSERT IGNORE INTO 當(dāng)插入數(shù)據(jù)時泳姐,在設(shè)置了記錄的唯一性后效拭,如果插入重復(fù)數(shù)據(jù),將不返回錯誤,只以警告形式返回缎患。 而 REPLACE INTO 如果存在 primary 或 unique 相同的記錄慕的,則先刪除掉。再插入新記錄挤渔。

另一種設(shè)置數(shù)據(jù)的唯一性方法是添加一個 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)
);
統(tǒng)計重復(fù)數(shù)據(jù)

以下我們將統(tǒng)計表中 first_name 和 last_name的重復(fù)記錄數(shù):

SELECT COUNT(*) as repetitions, last_name, first_name FROM person_tbl GROUP BY last_name, first_name HAVING repetitions > 1;

以上查詢語句將返回 person_tbl 表中重復(fù)的記錄數(shù)。 一般情況下蚂蕴,查詢重復(fù)的值低散,請執(zhí)行以下操作:

  • 確定哪一列包含的值可能會重復(fù)。
  • 在列選擇列表使用COUNT(*)列出的那些列骡楼。
  • 在GROUP BY子句中列出的列熔号。
  • HAVING子句設(shè)置重復(fù)數(shù)大于1。

過濾重復(fù)數(shù)據(jù)

如果你需要讀取不重復(fù)的數(shù)據(jù)可以在 SELECT 語句中使用 DISTINCT 關(guān)鍵字來過濾重復(fù)數(shù)據(jù)鸟整。

SELECT DISTINCT last_name, first_name FROM person_tbl;

你也可以使用 GROUP BY 來讀取數(shù)據(jù)表中不重復(fù)的數(shù)據(jù):

SELECT last_name, first_name FROM person_tbl GROUP BY (last_name, first_name);
刪除重復(fù)數(shù)據(jù)

如果你想刪除數(shù)據(jù)表中的重復(fù)數(shù)據(jù)引镊,你可以使用以下的SQL語句:

CREATE TABLE tmp SELECT last_name, first_name, sex FROM person_tbl  GROUP BY (last_name, first_name, sex);
DROP TABLE person_tbl;
ALTER TABLE tmp RENAME TO person_tbl;

當(dāng)然你也可以在數(shù)據(jù)表中添加 INDEX(索引) 和 PRIMAY KEY(主鍵)這種簡單的方法來刪除表中的重復(fù)記錄。方法如下:

ALTER IGNORE TABLE person_tbl ADD PRIMARY KEY (last_name, first_name);

SQL 注入

所謂SQL注入篮条,就是通過把SQL命令插入到Web表單遞交或輸入域名或頁面請求的查詢字符串弟头,最終達(dá)到欺騙服務(wù)器執(zhí)行惡意的SQL命令

防止SQL注入,我們需要注意以下幾個要點:

  1. 永遠(yuǎn)不要信任用戶的輸入涉茧。對用戶的輸入進(jìn)行校驗赴恨,可以通過正則表達(dá)式,或限制長度伴栓;對單引號和 雙"-"進(jìn)行轉(zhuǎn)換等伦连。
  2. 永遠(yuǎn)不要使用動態(tài)拼裝sql,可以使用參數(shù)化的sql或者直接使用存儲過程進(jìn)行數(shù)據(jù)查詢存取钳垮。
  3. 永遠(yuǎn)不要使用管理員權(quán)限的數(shù)據(jù)庫連接惑淳,為每個應(yīng)用使用單獨的權(quán)限有限的數(shù)據(jù)庫連接。
  4. 不要把機(jī)密信息直接存放饺窿,加密或者h(yuǎn)ash掉密碼和敏感的信息歧焦。
  5. 應(yīng)用的異常信息應(yīng)該給出盡可能少的提示,最好使用自定義的錯誤信息對原始錯誤信息進(jìn)行包裝
  6. sql注入的檢測方法一般采取輔助軟件或網(wǎng)站平臺來檢測肚医,軟件一般采用sql注入檢測工具jsky绢馍,網(wǎng)站平臺就有億思網(wǎng)站安全平臺檢測工具痕貌。MDCSOFT SCAN等糠排。采用MDCSOFT-IPS可以有效的防御SQL注入舵稠,XSS攻擊等。

函數(shù)

字符串函數(shù)
function.png
數(shù)字函數(shù)
function_number.png
日期函數(shù)
function_date.png
高級函數(shù)
function_high.png

運算符

算術(shù)運算符

MySQL 支持的算術(shù)運算符包括:

運算符 作用

    •      加法
      
    •      減法
      
    •      乘法
      
  • / 或 DIV 除法
  • % 或 MOD 取余

在除法運算和模運算中室琢,如果除數(shù)為0,將是非法除數(shù)盈滴,返回結(jié)果為NULL轿钠。

  1.  select 1+2;
     +-----+
     | 1+2 |
     +-----+
     |   3 |
     +-----+
    
  2.  select 1-2;
     +-----+
     | 1-2 |
     +-----+
     |  -1 |
     +-----+
    
  3.  select 2*3;
     +-----+
     | 2*3 |
     +-----+
     |   6 |
     +-----+
    
  4.  select 2/3;
     +--------+
     | 2/3    |
     +--------+
     | 0.6667 |
     +--------+  
    
  5.  select 10 DIV 4;
     +----------+
     | 10 DIV 4 |
     +----------+
     |        2 |
     +----------+            
    
  6.  select 10 MOD 4;
     +----------+
     | 10 MOD 4 |
     +----------+
     |        2 |
     +----------+    
    
比較運算符
comparison_operator.png
  1. 等于

     mysql> select 2=3;
     +-----+
     | 2=3 |
     +-----+
     |   0 |
     +-----+
     
     
     mysql> select NULL = NULL;
     +-------------+
     | NULL = NULL |
     +-------------+
     |        NULL |
     +-------------+ 
    
  2. 不等于

     mysql> select 2<>3;
     +------+
     | 2<>3 |
     +------+
     |    1 |
     +------+
    
  3. 不等于

與 = 的區(qū)別在于當(dāng)兩個操作碼均為 NULL 時症汹,其所得值為 1 而不為 NULL贷腕,而當(dāng)一個操作碼為 NULL 時泽裳,其所得值為 0而不為 NULL涮总。

    mysql> select 2<=>3;
    +-------+
    | 2<=>3 |
    +-------+
    |     0 |
    +-------+
    
    
    mysql> select null=null;
    +-----------+
    | null=null |
    +-----------+
    |      NULL |
    +-----------+
    
            
    mysql> select null<=>null;
    +-------------+
    | null<=>null |
    +-------------+
    |           1 |
    +-------------+

4夺克、小于

    mysql> select 2<3;
    +-----+
    | 2<3 |
    +-----+
    |   1 |
    +-----+

5铺纽、小于等于

mysql> select 2<=3;
+------+
| 2<=3 |
+------+
|    1 |
+------+

6狡门、大于

mysql> select 2>3;
+-----+
| 2>3 |
+-----+
|   0 |
+-----+

7其馏、大于等于

mysql> select 2>=3;
+------+
| 2>=3 |
+------+
|    0 |
+------+

8、BETWEEN

mysql> select 5 between 1 and 10;
+--------------------+
| 5 between 1 and 10 |
+--------------------+
|                  1 |
+--------------------+

9咖耘、IN

mysql> select 5 in (1,2,3,4,5);
+------------------+
| 5 in (1,2,3,4,5) |
+------------------+
|                1 |
+------------------+    

10儿倒、NOT IN

mysql> select 5 not in (1,2,3,4,5);
+----------------------+
| 5 not in (1,2,3,4,5) |
+----------------------+
|                    0 |
+----------------------+    

11夫否、IS NULL

mysql> select null is NULL;
+--------------+
| null is NULL |
+--------------+
|            1 |
+--------------+

mysql> select 'a' is NULL;
+-------------+
| 'a' is NULL |
+-------------+
|           0 |
+-------------+ 

12凰慈、IS NOT NULL

mysql> select null IS NOT NULL;
+------------------+
| null IS NOT NULL |
+------------------+
|                0 |
+------------------+

        
mysql> select 'a' IS NOT NULL;
+-----------------+
| 'a' IS NOT NULL |
+-----------------+
|               1 |
+-----------------+ 

13溉瓶、LIKE

mysql> select '12345' like '12%';
+--------------------+
| '12345' like '12%' |
+--------------------+
|                  1 |
+--------------------+

mysql> select '12345' like '12_';
+--------------------+
| '12345' like '12_' |
+--------------------+
|                  0 |
+--------------------+

14堰酿、REGEXP

mysql> select 'beijing' REGEXP 'jing';
+-------------------------+
| 'beijing' REGEXP 'jing' |
+-------------------------+
|                       1 |
+-------------------------+

mysql> select 'beijing' REGEXP 'xi';
+-----------------------+
| 'beijing' REGEXP 'xi' |
+-----------------------+
|                     0 |
+-----------------------+   
邏輯運算符

邏輯運算符用來判斷表達(dá)式的真假触创。如果表達(dá)式是真哼绑,結(jié)果返回 1抖韩。如果表達(dá)式是假茂浮,結(jié)果返回 0席揽。

  • NOT 或 ! 邏輯非
  • AND 邏輯與
  • OR 邏輯或
  • XOR 邏輯異或
  1.  mysql> select 2 and 0;
     +---------+
     | 2 and 0 |
     +---------+
     |       0 |
     +---------+
         
             
     mysql> select 2 and 1;   
     +---------+     
     | 2 and 1 |      
     +---------+      
     |       1 |      
     +---------+
    
  2.  mysql> select 2 or 0;
     +--------+
     | 2 or 0 |
     +--------+
     |      1 |
     +--------+
     
     mysql> select 2 or 1;
     +--------+
     | 2 or 1 |
     +--------+
     |      1 |
     +--------+
     
     mysql> select 0 or 0;
     +--------+
     | 0 or 0 |
     +--------+
     |      0 |
     +--------+
     
     mysql> select 1 || 0;
     +--------+
     | 1 || 0 |
     +--------+
     |      1 |
     +--------+
    
  3.  mysql> select not 1;
     +-------+
     | not 1 |
     +-------+
     |     0 |
     +-------+
     
     mysql> select !0;
     +----+
     | !0 |
     +----+
     |  1 |
     +----+
    

4幌羞、異或

mysql> select 1 xor 1;
+---------+
| 1 xor 1 |
+---------+
|       0 |
+---------+

mysql> select 0 xor 0;
+---------+
| 0 xor 0 |
+---------+
|       0 |
+---------+

mysql> select 1 xor 0;
+---------+
| 1 xor 0 |
+---------+
|       1 |
+---------+

mysql> select null or 1;
+-----------+
| null or 1 |
+-----------+
|         1 |
+-----------+

mysql> select 1 ^ 0;
+-------+
| 1 ^ 0 |
+-------+
|     1 |
+-------+   
位運算符

位運算符是在二進(jìn)制數(shù)上進(jìn)行計算的運算符熊痴。位運算會先將操作數(shù)變成二進(jìn)制數(shù)聂宾,進(jìn)行位運算亏吝。然后再將計算結(jié)果從二進(jìn)制數(shù)變回十進(jìn)制數(shù)蔚鸥。

  • & 按位與
  • | 按位或
  • ^ 按位異或
  • ! 取反
  • << 左移
  • >> 右移
  1. 按位與
    mysql> select 3&5;
    +-----+
    | 3&5 |
    +-----+
    |   1 |
    +-----+
  1. 按位或

     mysql> select 3|5;
     +-----+
     | 3|5 |
     +-----+
     |   7 |
     +-----+
    
  2. 按位異或

     mysql> select 3^5;
     +-----+
     | 3^5 |
     +-----+
     |   6 |
     +-----+
    
  3. 按位取反

     mysql> select ~18446744073709551612;
     +-----------------------+
     | ~18446744073709551612 |
     +-----------------------+
     |                     3 |
     +-----------------------+
    
  4. 按位右移

     mysql> select 3>>1;
     +------+
     | 3>>1 |
     +------+
     |    1 |
     +------+
    
  5. 按位左移

     mysql> select 3<<1;
     +------+
     | 3<<1 |
     +------+
     |    6 |
     +------+
    
運算符優(yōu)先級
  • 最低優(yōu)先級為: :=馆类。

  • 最高優(yōu)先級為: !乾巧、BINARY预愤、 COLLATE植康。

priority.png

count()函數(shù)

  • count()函數(shù)是用來統(tǒng)計表中記錄的一個函數(shù)供璧,返回匹配條件的行數(shù)睡毒。
count()語法:
  • count(*)---包括所有列冗栗,返回表中的記錄數(shù)贞瞒,相當(dāng)于統(tǒng)計表的行數(shù)军浆,在統(tǒng)計結(jié)果的時候乒融,不會忽略列值為NULL的記錄赞季。

  • count(1)---忽略所有列申钩,1表示一個固定值撒遣,也可以用count(2)义黎、count(3)代替廉涕,在統(tǒng)計結(jié)果的時候狐蜕,不會忽略列值為NULL的記錄层释。

  • count(列名)---只包括列名指定列湃累,返回指定列的記錄數(shù)治力,在統(tǒng)計結(jié)果的時候宵统,會忽略列值為NULL的記錄(不包括空字符串和0),即列值為NULL的記錄不統(tǒng)計在內(nèi)瓢省。

  • count(distinct 列名)---只包括列名指定列勤婚,返回指定列的不同值的記錄數(shù)馒胆,在統(tǒng)計結(jié)果的時候祝迂,在統(tǒng)計結(jié)果的時候型雳,會忽略列值為NULL的記錄(不包括空字符串和0)纠俭,即列值為NULL的記錄不統(tǒng)計在內(nèi)柑晒。

count(*)&count(1)&count(列名)執(zhí)行效率比較:

(1)如果列為主鍵匙赞,count(列名)效率優(yōu)于count(1)

(2)如果列不為主鍵涌庭,count(1)效率優(yōu)于count(列名)

(3)如果表中存在主鍵坐榆,count(主鍵列名)效率最優(yōu)

(4)如果表中只有一列席镀,則count(*)效率最優(yōu)

(5)如果表有多列豪诲,且不存在主鍵服赎,則count(1)效率優(yōu)于count(*)

因為count(*)和count(1)統(tǒng)計過程中不會忽略列值為NULL的記錄交播,所以可以通過以下兩種方式來統(tǒng)計列值為NULL的記錄數(shù):

select count(*) from table where is_active is null;
select count(1) from table where is_active is null;

特例

select count('') from table;-返回表的記錄數(shù)
select count(0) from table;-返回表的記錄數(shù)
select count(null) from table;-返回0

AS

可理解為:用作缺厉、當(dāng)成芽死,作為关贵;一般是重命名列名或者表名揖曾。(主要為了查詢方便)

<表名> [AS] <別名>
select  column_1  as  列1,column_2 as  列2   from  text as  表;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末炭剪,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子错妖,更是在濱河造成了極大的恐慌暂氯,老刑警劉巖痴施,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件辣吃,死亡現(xiàn)場離奇詭異齿尽,居然都是意外死亡循头,警方通過查閱死者的電腦和手機(jī)卡骂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來浓若,“玉大人挪钓,你說我怎么就攤上這事碌上×笥瑁” “怎么了霞丧?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵敷燎,是天一觀的道長硬贯。 經(jīng)常有香客問我饭豹,道長拄衰,這世上最難降的妖魔是什么翘悉? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮制市,結(jié)果婚禮上祥楣,老公的妹妹穿的比我還像新娘误褪。我一直安慰自己兽间,他們只是感情好渡八,可當(dāng)我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著逮壁,像睡著了一般窥淆。 火紅的嫁衣襯著肌膚如雪忧饭。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天吼砂,我揣著相機(jī)與錄音渔肩,去河邊找鬼周偎。 笑死,一個胖子當(dāng)著我的面吹牛袍嬉,可吹牛的內(nèi)容都是我干的伺通。 我是一名探鬼主播罐监,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼沟堡,長吁一口氣:“原來是場噩夢啊……” “哼航罗!你這毒婦竟也來了粥血?” 一聲冷哼從身側(cè)響起复亏,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎耕突,沒想到半個月后有勾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡雇逞,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了掉蔬。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片女轿。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡傅寡,死狀恐怖荐操,靈堂內(nèi)的尸體忽然破棺而出托启,到底是詐尸還是另有隱情唉堪,我是刑警寧澤唠亚,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布祟蚀,位于F島的核電站割卖,受9級特大地震影響前酿,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜鹏溯,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一罢维、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧丙挽,春花似錦肺孵、人聲如沸颜阐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽凳怨。三九已至瑰艘,卻和暖如春是鬼,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背紫新。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工屑咳, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人弊琴。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓兆龙,卻偏偏與公主長得像,于是被迫代替她去往敵國和親敲董。 傳聞我的和親對象是個殘疾皇子紫皇,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 什么是數(shù)據(jù)庫? 數(shù)據(jù)庫是存儲數(shù)據(jù)的集合的單獨的應(yīng)用程序腋寨。每個數(shù)據(jù)庫具有一個或多個不同的API聪铺,用于創(chuàng)建,訪問萄窜,管理...
    chen_000閱讀 4,030評論 0 19
  • 作者:燁竹 數(shù)據(jù)庫的基本操作 登陸MySQL數(shù)據(jù)庫服務(wù):mysql -h服務(wù)器地址 -P端口號 -u用戶名 ...
    DragonRat閱讀 1,361評論 0 7
  • 1. 了解SQL 1.1 數(shù)據(jù)庫基礎(chǔ) ? 學(xué)習(xí)到目前這個階段铃剔,我們就需要以某種方式與數(shù)據(jù)庫打交道。在深入學(xué)習(xí)MyS...
    鋒享前端閱讀 1,042評論 0 1
  • MySQL技術(shù)內(nèi)幕:SQL編程 姜承堯 第1章 SQL編程 >> B是由MySQL創(chuàng)始人之一Monty分支的一個版...
    沉默劍士閱讀 2,405評論 0 3
  • 輪回又稱流轉(zhuǎn)查刻、輪轉(zhuǎn)键兜、生死輪回,意思是眾生生死死穗泵,在死亡后普气,靈魂又輪回重新投胎成為另一個人,像車輪一樣轉(zhuǎn)動不停佃延,循環(huán)...
    山中撿石閱讀 125評論 0 1