mysql基礎之視圖、事務、索引、外鍵

1、視圖

  視圖是一個虛擬表,其內容由查詢定義。同真實的表同樣,視圖包含一系列帶有名稱的列和行數據。可是,視圖並不在數據庫中以存儲的數據值集形式存在。行和列數據來自由定義視圖的查詢所引用的表,而且在引用視圖時動態生成。對其中所引用的基礎表來講,視圖的做用相似於篩選。定義視圖的篩選能夠來自當前或其它數據庫的一個或多個表,或者其它視圖。經過視圖進行查詢沒有任何限制,經過它們進行數據修改時的限制也不多。視圖是存儲在數據庫中的查詢的SQL 語句,它主要出於兩種緣由:安全緣由, 視圖能夠隱藏一些數據;簡化操做。mysql

查看當前用戶是否擁有建立視圖的權限:算法

複製代碼
MariaDB [bi]> select user();
+----------------+
| user()         |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)

MariaDB [bi]> select create_view_priv,select_priv from mysql.user where user='root' and host='localhost';
+------------------+-------------+
| create_view_priv | select_priv |
+------------------+-------------+
| Y                | Y           |
+------------------+-------------+
1 row in set (0.00 sec)
複製代碼

一、建立視圖sql

格式:CREATE VIEW 視圖名稱 AS SQL語句數據庫

MariaDB [bi]> create view v_class_stu as select s.name,c.name as class_name from students as s inner join classes as c on s.cls_id=c.id order by c.name;

二、查看視圖緩存

複製代碼
MariaDB [bi]> show tables;
+---------------+
| Tables_in_bi |
+---------------+
| areas         |
| classes       |
| create_index  |
| students      |
| t1            |
| t2            |
| test          |
| v_class_stu   |
+---------------+
8 rows in set (0.00 sec)

MariaDB [bi]> select * from v_class_stu;
+--------------+--------------+
| name         | class_name   |
+--------------+--------------+
| 黃蓉         | 運維一班     |
| 錢小豪       | 運維一班     |
| 彭于晏       | 運維一班     |
| 周杰         | 運維一班     |
| 小明         | 運維一班     |
| 周杰倫兒     | 運維一班     |
| 陳冠希       | 運維一班     |
| 王祖賢       | 運維一班     |
| 謝霆鋒       | 運維一班     |
| 劉亦菲       | 運維三班     |
|              | 運維三班     |
| 劉德華       | 運維二班     |
| 小月月       | 運維二班     |
| 和珅         | 運維二班     |
| 程坤         | 運維二班     |
| 鳳姐         | 運維二班     |
+--------------+--------------+
16 rows in set (0.00 sec)
複製代碼

三、修改視圖安全

複製代碼
MariaDB [bi]> alter view v_class_stu as select c.name as class_name ,s.name,s.age,s.high from students as s inner join classes as c on s.cls_id=c.id order by c.name,s.age asc;
Query OK, 0 rows affected (0.00 sec)

MariaDB [bi]> select * from v_class_stu;
+--------------+--------------+------+--------+
| class_name   | name         | age  | high   |
+--------------+--------------+------+--------+
| 運維一班     | 小明         |   18 | 180.00 |
| 運維一班     | 彭于晏       |   28 | 185.00 |
| 運維一班     | 周杰         |   33 | 178.00 |
| 運維一班     | 周杰倫兒     |   34 |   NULL |
| 運維一班     | 陳冠希       |   38 | 175.00 |
| 運維一班     | 謝霆鋒       |   38 | 175.00 |
| 運維一班     | 王祖賢       |   52 | 170.00 |
| 運維一班     | 錢小豪       |   56 | 178.00 |
| 運維一班     | 黃蓉         |  108 | 160.00 |
| 運維三班     |              |    0 |   NULL |
| 運維三班     | 劉亦菲       |   29 | 162.00 |
| 運維二班     | 小月月       |   19 | 180.00 |
| 運維二班     | 程坤         |   44 | 181.00 |
| 運維二班     | 鳳姐         |   44 | 150.00 |
| 運維二班     | 和珅         |   55 | 166.00 |
| 運維二班     | 劉德華       |   58 | 175.00 |
+--------------+--------------+------+--------+
16 rows in set (0.00 sec)
複製代碼

四、刪除視圖運維

DROP VIEW 視圖名稱函數

五、使用:視圖的用途就是查詢(虛擬表,沒法使用視圖對真實表進行建立、更新和刪除操做)性能

SELECT * FROM VIEW測試

2、事務

  事務用於將某些操做的多個SQL做爲原子性操做,一旦有某一個出現錯誤,便可回滾到原來的狀態,從而保證數據庫數據完整性。事務普遍的運用於訂單系統、銀行系統等多種場景。例如:當兩張銀行卡之間進行轉帳,甲方錢轉出去了,忽然光纜壞了,乙方還沒收到錢,錢跑哪裏去了,就爲了防止這種狀況,事務就出來了,事務能夠防止這種事情發生。

  事務具備ACID特性:原子性(A,atomicity)、一致性(C,consistency)、隔離性(I,isolation)、持久性(D,durability)。

  原子性:整個事務中的全部操做要麼所有執行成功,要麼所有執行失敗後回滾到最初狀態,它是一個不可分割的工做單位。

  一致性:數據庫老是從一個一致性的狀態轉換到另外一個一致性的狀態。

  隔離性:一個事物所作的修改在最終提交以前,對其餘事物是不可見的。

  持久性:事務完成後,該事務內涉及的數據必須持久性的寫入磁盤保證其持久性。固然,這是從事務的角度來考慮的的持久性,從操做系統故障或硬件故障來講,這是不必定的。

事務命令
  要求:表的引擎類型必須是innodb類型纔可使用事務,這是mysql表的默認引擎
  查看錶的建立語句,能夠看到engine=innodb

複製代碼
MariaDB [bi]> show create table students\G;
*************************** 1. row ***************************
       Table: students
Create Table: CREATE TABLE `students` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT '',
  `age` tinyint(3) unsigned DEFAULT 0,
  `high` decimal(5,2) DEFAULT NULL,
  `gender` enum('男','女','中性','保密') DEFAULT '保密',
  `cls_id` int(10) unsigned DEFAULT 0,
  `is_delete` bit(1) DEFAULT b'0',
  PRIMARY KEY (`id`),
  KEY `fk` (`cls_id`),
  CONSTRAINT `fk` FOREIGN KEY (`cls_id`) REFEbiCES `classes` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8
修改數據的命令會觸發事務,包含insert,update,delete
複製代碼

開啓事務(開啓事務後執行修改命令,變動會維護到本地緩存中,而不維護到物理表中)
  begin或者start transaction;
關閉事務(提交--將緩存中的數據變動維護到物理表中)或者(回滾事務--放棄緩存中變動的數據)
  commit或者rollback;

3、索引

   索引是對數據庫表中一個或多個列(例如,students表的姓名 (name) 列)的值進行排序的結構。若是想按特定職員的姓來查找他或她,則與在表中搜索全部的行相比,索引有助於更快地獲取信息。

  例如這樣一個查詢:select * from test1 where id=10000。若是沒有索引,必須遍歷整個表,直到ID等於10000的這一行被找到爲止;有了索引以後(必須是在ID這一列上創建的索引),便可在索引中查找。因爲索引是通過某種算法優化過的,於是查找次數要少的多。可見,索引插敘的速度要比沒有索引的速度要快不少。

  索引能夠加快查詢速度,但並非越多越好,由於若是數據庫有大量增刪改的話,修改數據的同時對應的索引也要被修改,所以會大大下降數據庫性能。

MySQL中常見索引有:

  • 普通索引
  • 惟一索引
  • 主鍵索引
  • 組合索引

 一、普通索引(index)

普通索引只有一個功能,就是加快查找速度

(1)建立索引

複製代碼
方法一:在建立表的時候建立索引
    create table create_index(
    id int primary key,
    name varchar(10) unique,
    age int,
    key (age)
    );
方法二:在已經存在的表上建立索引
    create index 索引名稱 on 表名(字段名稱)
    例:
    create index age_index on create_index(age);
複製代碼

(2)查看索引

show index from 表名;
複製代碼
MariaDB [bi]> create index age_index on students(age);
Query OK, 0 rows affected (0.05 sec)
Records: 0  Duplicates: 0  Warnings: 0
MariaDB [bi]> show index from students\G;
*************************** 1. row ***************************
        Table: students
   Non_unique: 0
     Key_name: PRIMARY
 Seq_in_index: 1
  Column_name: id
    Collation: A
  Cardinality: 15
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE
      Comment: 
Index_comment: *************************** 2. row ***************************
        Table: students
   Non_unique: 1
     Key_name: age_index
 Seq_in_index: 1
  Column_name: age
    Collation: A
  Cardinality: 15
     Sub_part: NULL
       Packed: NULL
         Null: YES
   Index_type: BTREE
      Comment: 
Index_comment: 
3 rows in set (0.00 sec)

ERROR: No query specified
複製代碼

(3)刪除索引

drop index 索引名稱 on 表名;

(4)注意事項(對於建立索引時若是是BLOB和TEXT類型,必須指定length)

create index index_name on tab1(extra(32));

時間測試:

show variable like 'profiling';
set profiling=1;#打開sql語句執行時間
show profiles;#查看sql執行時間

二、惟一索引(unique)

  惟一性索引unique index和通常索引normal index最大的差別就是在索引列上增長了一層惟一約束。添加惟一性索引的數據列能夠爲空,可是隻要存在數據值,就必須是惟一的。

(1)建立表+惟一索引

複製代碼
MariaDB [bi]> create table test2 (
    -> id int not null auto_increment primary key,
    -> name varchar(32) not null,
    -> extra text,
    -> unique index_name (name)
    -> );
Query OK, 0 rows affected (0.00 sec)
MariaDB [bi]> show index from test2\G;
*************************** 1. row ***************************
        Table: test2
   Non_unique: 0
     Key_name: PRIMARY
 Seq_in_index: 1
  Column_name: id
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE
      Comment: 
Index_comment: 
*************************** 2. row ***************************
        Table: test2
   Non_unique: 0
     Key_name: index_name
 Seq_in_index: 1
  Column_name: name
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE
      Comment: 
Index_comment: 
2 rows in set (0.00 sec)
複製代碼

(2)建立索引

create unique index 索引名 on 表名(列名)

(3)刪除索引

drop unique index 索引名 on 表名

三、主鍵索引

  在數據庫關係圖中爲表定義一個主鍵將自動建立主鍵索引,主鍵索引是惟一索引的特殊類型。主鍵索引要求主鍵中的每一個值是惟一的。當在查詢中使用主鍵索引時,它還容許快速訪問數據。數據不能爲空

(1)建立表+主鍵索引

複製代碼
MariaDB [bi]> create table test3 (
    -> id int not null auto_increment,
    -> name varchar(32) not null,
    -> extra text,
    -> primary key(id),
    -> index index_name (name)
    -> );
Query OK, 0 rows affected (0.00 sec)

MariaDB [bi]> show index from test3\G;
*************************** 1. row ***************************
        Table: test3
   Non_unique: 0
     Key_name: PRIMARY
 Seq_in_index: 1
  Column_name: id
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE
      Comment: 
Index_comment: 
*************************** 2. row ***************************
        Table: test3
   Non_unique: 1
     Key_name: index_name
 Seq_in_index: 1
  Column_name: name
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE
      Comment: 
Index_comment: 
2 rows in set (0.00 sec)
複製代碼

(2)建立主鍵

alter table 表名 add primary key(列名);

(3)刪除主鍵

alter table 表名 drop primary key;
alter table 表名  modify  列名 int, drop primary key;

四、組合索引

組合索引,就是組合查詢的意思,將兩列或者多列組合成一個索引進行查詢

其應用場景爲:頻繁的同時使用n列來進行查詢,如:where name = '謝霆鋒' and age=38;

複製代碼
建立表:
MariaDB [bi]> create table test4 ( -> id int not null auto_increment primary key, -> name varchar(32) not null, -> phone int(11) unsigned, -> extra text -> ); Query OK, 0 rows affected (0.03 sec) 建立組合索引: MariaDB [bi]> create index index_na_ph on test4(name,phone); Query OK, 0 rows affected (0.01 sec) Records: 0 Duplicates: 0 Warnings: 0 MariaDB [bi]> show index from test4\G; *************************** 1. row *************************** Table: test4 Non_unique: 0 Key_name: PRIMARY Seq_in_index: 1 Column_name: id Collation: A Cardinality: 0 Sub_part: NULL Packed: NULL Null: Index_type: BTREE Comment: Index_comment: *************************** 2. row *************************** Table: test4 Non_unique: 1 Key_name: index_na_ph Seq_in_index: 1 Column_name: name Collation: A Cardinality: 0 Sub_part: NULL Packed: NULL Null: Index_type: BTREE Comment: Index_comment: *************************** 3. row *************************** Table: test4 Non_unique: 1 Key_name: index_na_ph Seq_in_index: 2 Column_name: phone Collation: A Cardinality: 0 Sub_part: NULL Packed: NULL Null: YES Index_type: BTREE Comment: Index_comment: 3 rows in set (0.00 sec)
複製代碼

五、注意事項

  數據庫表中添加索引後可以讓查詢數據庫速度飛快,但前提必須是正確的使用索引來查詢,若是以錯誤的方式使用,則即便創建索引也會不奏效。

下面這些狀況不會使用到索引:

複製代碼
一、like '%xx'
    select * from tb1 where name like '%cn';

二、使用函數
    select * from tb1 where reverse(name) = '張巖林';

三、or
    select * from tb1 where nid = 1 or email='zhangyanlin@live.com';
    特別的:當or條件中有未創建索引的列才失效,如下會走索引
            select * from tb1 where nid = 1 or name = 'zhangyanlin';
            select * from tb1 where nid = 1 or email = 'zhangyanlin@live.com' and name = 'aylin'

四、類型不一致
    若是列是字符串類型,傳入條件是必須用引號引發來,否則...
    select * from tb1 where name = 999;

五、 !=
    select * from tb1 where name != 'aylin'
    特別的:若是是主鍵,則仍是會走索引
        select * from tb1 where nid != 123

六、 >
    select * from tb1 where name > 'alex'
    特別的:若是是主鍵或索引是整數類型,則仍是會走索引
        select * from tb1 where nid > 123
        select * from tb1 where num > 123

七、order by
    select email from tb1 order by name desc;
    當根據索引排序時候,選擇的映射若是不是索引,則不走索引
    特別的:若是對主鍵排序,則仍是走索引:
        select * from tb1 order by nid desc;
 
八、 組合索引最左前綴
    若是組合索引爲:(name,email)
    name and email       -- 使用索引
    name                 -- 使用索引
    email                -- 不使用索引
複製代碼

其它注意事項:

複製代碼
一、避免使用select *
二、count(1)或count(列) 代替 count(*)
三、建立表時儘可能時 char 代替 varchar
四、表的字段順序固定長度的字段優先
五、組合索引代替多個單列索引(常用多個條件查詢時)
六、儘可能使用短索引
七、使用鏈接(JOIN)來代替子查詢(Sub-Queries)
八、連表時注意條件類型需一致
九、索引散列值(重複少)不適合建索引,例:性別不適合
複製代碼

4、外鍵(foreign key)

  若是一個實體的某個字段指向另外一個實體的主鍵,就稱爲外鍵。被指向的實體,稱之爲主實體(主表),也叫父實體(父表)。負責指向的實體,稱之爲從實體(從表),也叫子實體(子表)
  添加外鍵(建立外鍵時從表和主表相關聯的字段要一一對應,不然的話沒法建立成功)
  (同時,從表的字段類型須要和主表的主鍵字段的類型保持一致)

  對關係字段進行約束,當爲從表中的關係字段填寫值時,會到關聯的主表中查詢此值是否存在,若是存在則填寫成功,若是不存在則填寫失敗並報錯

(1)添加外鍵

複製代碼
MariaDB [testdb]> alter table students add constraint 外鍵名字 foreign key (字段) refebices 表名(字段) on delete cascade;
constraint(/kən'stbit/,約束,約束條件,強制)refebices(/'rɛfərənsɪz/,參考文獻,把...引做參考)cascade(/kæ'sked/,級聯,串聯,瀑布)
note:
    若是加上on delete cascade那麼在刪除父表中的數據時,也會刪除子表中的數據
    若是不加on delete cascade那麼若是子表不爲空,不能刪除父表數據
複製代碼

(2)查看外鍵

複製代碼
MariaDB [bi]> show create table students\G;
*************************** 1. row ***************************
       Table: students
Create Table: CREATE TABLE `students` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT '',
  `age` tinyint(3) unsigned DEFAULT 0,
  `high` decimal(5,2) DEFAULT NULL,
  `gender` enum('男','女','中性','保密') DEFAULT '保密',
  `cls_id` int(10) unsigned DEFAULT 0,
  `is_delete` bit(1) DEFAULT b'0',
  PRIMARY KEY (`id`),
  KEY `fk` (`cls_id`),
  KEY `age_index` (`age`),
  CONSTRAINT `fk` FOREIGN KEY (`cls_id`) REFEbiCES `classes` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
複製代碼

(3)刪除外鍵

alter table students drop foreign key 外鍵名字
相關文章
相關標籤/搜索