1. 程式人生 > >數據庫 設計 和多表查詢

數據庫 設計 和多表查詢

分享圖片 rim empty 我們 兩個 相關 缺點 upd 全部

#1、首先明確一點:分組發生在where之後,即分組是基於where之後得到的記錄而進行的

#2、分組指的是:將所有記錄按照某個相同字段進行歸類,比如針對員工信息表的職位分組,或者按照性別進行分組等

#3、為何要分組呢?
    取每個部門的最高工資
    取每個部門的員工數
    取男人數和女人數

小竅門:‘每’這個字後面的字段,就是我們分組的依據


#4、大前提:
    可以按照任意字段分組,但是分組完畢後,比如group by post,只能查看post字段,如果想查看組內信息,需要借助於聚合函數
技術分享圖片 技術分享圖片
單獨使用GROUP BY關鍵字分組
    SELECT post FROM employee GROUP BY post;
    註意:我們按照post字段分組,那麽select查詢的字段只能是post,想要獲取組內的其他相關信息,需要借助函數

GROUP BY關鍵字和GROUP_CONCAT()函數一起使用
    SELECT post,GROUP_CONCAT(name) FROM employee GROUP BY post;#按照崗位分組,並查看組內成員名
    SELECT post,GROUP_CONCAT(name) as emp_members FROM employee GROUP BY post;

GROUP BY與聚合函數一起使用
    select post,count(id) as count from employee group by post;#按照崗位分組,並查看每個組有多少人
技術分享圖片

聚合函數

技術分享圖片
#強調:聚合函數聚合的是組的內容,若是沒有分組,則默認一組

示例:
    SELECT COUNT(*) FROM employee;
    SELECT COUNT(*) FROM employee WHERE depart_id=1;
    SELECT MAX(salary) FROM employee;
    SELECT MIN(salary) FROM employee;
    SELECT AVG(salary) FROM employee;
    SELECT SUM(salary) FROM employee;
    SELECT SUM(salary) FROM employee WHERE depart_id=3;
技術分享圖片

HAVING過濾

having用於分組之後的條件查詢

限制查詢的記錄數:LIMIT

技術分享圖片
示例:
    SELECT * FROM employee ORDER BY salary DESC 
        LIMIT 3;                    #默認初始位置為0 
    
    SELECT * FROM employee ORDER BY salary DESC
        LIMIT 0,5; #從第0開始,即先查詢出第一條,然後包含這一條在內往後查5條

    SELECT * FROM employee ORDER BY salary DESC
        LIMIT 5,5; #從第5開始,即先查詢出第6條,然後包含這一條在內往後查5條
技術分享圖片

使用正則表達式查詢

技術分享圖片
SELECT * FROM employee WHERE name REGEXP ‘^ale‘;

SELECT * FROM employee WHERE name REGEXP ‘on$‘;

SELECT * FROM employee WHERE name REGEXP ‘m{2}‘;


小結:對字符串匹配的方式
WHERE name = ‘egon‘;
WHERE name LIKE ‘yua%‘;
WHERE name REGEXP ‘on$‘
技術分享圖片

多表查詢

多表連接查詢

#重點:外鏈接語法

SELECT 字段列表
    FROM 表1 INNER|LEFT|RIGHT JOIN 表2
    ON 表1.字段 = 表2.字段;

交叉連接:不適用任何匹配條件。生成笛卡爾積

技術分享圖片 技術分享圖片
mysql> select * from employee,department;
+----+------------+--------+------+--------+------+--------------+
| id | name       | sex    | age  | dep_id | id   | name         |
+----+------------+--------+------+--------+------+--------------+
|  1 | egon       | male   |   18 |    200 |  200 | 技術         |
|  1 | egon       | male   |   18 |    200 |  201 | 人力資源     |
|  1 | egon       | male   |   18 |    200 |  202 | 銷售         |
|  1 | egon       | male   |   18 |    200 |  203 | 運營         |
|  2 | alex       | female |   48 |    201 |  200 | 技術         |
|  2 | alex       | female |   48 |    201 |  201 | 人力資源     |
|  2 | alex       | female |   48 |    201 |  202 | 銷售         |
|  2 | alex       | female |   48 |    201 |  203 | 運營         |
|  3 | wupeiqi    | male   |   38 |    201 |  200 | 技術         |
|  3 | wupeiqi    | male   |   38 |    201 |  201 | 人力資源     |
|  3 | wupeiqi    | male   |   38 |    201 |  202 | 銷售         |
|  3 | wupeiqi    | male   |   38 |    201 |  203 | 運營         |
|  4 | yuanhao    | female |   28 |    202 |  200 | 技術         |
|  4 | yuanhao    | female |   28 |    202 |  201 | 人力資源     |
|  4 | yuanhao    | female |   28 |    202 |  202 | 銷售         |
|  4 | yuanhao    | female |   28 |    202 |  203 | 運營         |
|  5 | liwenzhou  | male   |   18 |    200 |  200 | 技術         |
|  5 | liwenzhou  | male   |   18 |    200 |  201 | 人力資源     |
|  5 | liwenzhou  | male   |   18 |    200 |  202 | 銷售         |
|  5 | liwenzhou  | male   |   18 |    200 |  203 | 運營         |
|  6 | jingliyang | female |   18 |    204 |  200 | 技術         |
|  6 | jingliyang | female |   18 |    204 |  201 | 人力資源     |
|  6 | jingliyang | female |   18 |    204 |  202 | 銷售         |
|  6 | jingliyang | female |   18 |    204 |  203 | 運營         |
+----+------------+--------+------+--------+------+--------------+
技術分享圖片

內連接:只連接匹配的行

技術分享圖片
#找兩張表共有的部分,相當於利用條件從笛卡爾積結果中篩選出了正確的結果
#department沒有204這個部門,因而employee表中關於204這條員工信息沒有匹配出來
mysql> select employee.id,employee.name,employee.age,employee.sex,department.name from employee inner join department on employee.dep_id=department.id; 
+----+-----------+------+--------+--------------+
| id | name      | age  | sex    | name         |
+----+-----------+------+--------+--------------+
|  1 | egon      |   18 | male   | 技術         |
|  2 | alex      |   48 | female | 人力資源     |
|  3 | wupeiqi   |   38 | male   | 人力資源     |
|  4 | yuanhao   |   28 | female | 銷售         |
|  5 | liwenzhou |   18 | male   | 技術         |
+----+-----------+------+--------+--------------+

#上述sql等同於
mysql> select employee.id,employee.name,employee.age,employee.sex,department.name from employee,department where employee.dep_id=department.id;
技術分享圖片

外鏈接之左連接:優先顯示左表全部記錄

技術分享圖片
#以左表為準,即找出所有員工信息,當然包括沒有部門的員工
#本質就是:在內連接的基礎上增加左邊有右邊沒有的結果
mysql> select employee.id,employee.name,department.name as depart_name from employee left join department on employee.dep_id=department.id;
+----+------------+--------------+
| id | name       | depart_name  |
+----+------------+--------------+
|  1 | egon       | 技術         |
|  5 | liwenzhou  | 技術         |
|  2 | alex       | 人力資源     |
|  3 | wupeiqi    | 人力資源     |
|  4 | yuanhao    | 銷售         |
|  6 | jingliyang | NULL         |
+----+------------+--------------+
技術分享圖片

外鏈接之右連接:優先顯示右表全部記錄

技術分享圖片
#以右表為準,即找出所有部門信息,包括沒有員工的部門
#本質就是:在內連接的基礎上增加右邊有左邊沒有的結果
mysql> select employee.id,employee.name,department.name as depart_name from employee right join department on employee.dep_id=department.id;
+------+-----------+--------------+
| id   | name      | depart_name  |
+------+-----------+--------------+
|    1 | egon      | 技術         |
|    2 | alex      | 人力資源     |
|    3 | wupeiqi   | 人力資源     |
|    4 | yuanhao   | 銷售         |
|    5 | liwenzhou | 技術         |
| NULL | NULL      | 運營         |
+------+-----------+--------------+
技術分享圖片

全外連接:顯示左右兩個表全部記錄

技術分享圖片
全外連接:在內連接的基礎上增加左邊有右邊沒有的和右邊有左邊沒有的結果
#註意:mysql不支持全外連接 full JOIN
#強調:mysql可以使用此種方式間接實現全外連接
select * from employee left join department on employee.dep_id = department.id
union
select * from employee right join department on employee.dep_id = department.id
;
#查看結果
+------+------------+--------+------+--------+------+--------------+
| id   | name       | sex    | age  | dep_id | id   | name         |
+------+------------+--------+------+--------+------+--------------+
|    1 | egon       | male   |   18 |    200 |  200 | 技術         |
|    5 | liwenzhou  | male   |   18 |    200 |  200 | 技術         |
|    2 | alex       | female |   48 |    201 |  201 | 人力資源     |
|    3 | wupeiqi    | male   |   38 |    201 |  201 | 人力資源     |
|    4 | yuanhao    | female |   28 |    202 |  202 | 銷售         |
|    6 | jingliyang | female |   18 |    204 | NULL | NULL         |
| NULL | NULL       | NULL   | NULL |   NULL |  203 | 運營         |
+------+------------+--------+------+--------+------+--------------+

#註意 union與union all的區別:union會去掉相同的紀錄
技術分享圖片

符合條件連接查詢

技術分享圖片
#示例1:以內連接的方式查詢employee和department表,並且employee表中的age字段值必須大於25,即找出年齡大於25歲的員工以及員工所在的部門
select employee.name,department.name from employee inner join department
    on employee.dep_id = department.id
    where age > 25;

#示例2:以內連接的方式查詢employee和department表,並且以age字段的升序方式顯示
select employee.id,employee.name,employee.age,department.name from employee,department
    where employee.dep_id = department.id
    and age > 25
    order by age asc;
技術分享圖片

子查詢

#1:子查詢是將一個查詢語句嵌套在另一個查詢語句中。
#2:內層查詢語句的查詢結果,可以為外層查詢語句提供查詢條件。
#3:子查詢中可以包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等關鍵字
#4:還可以包含比較運算符:= 、 !=、> 、<等

帶IN關鍵字的子查詢

技術分享圖片
#查詢平均年齡在25歲以上的部門名
select id,name from department
    where id in 
        (select dep_id from employee group by dep_id having avg(age) > 25);

#查看技術部員工姓名
select name from employee
    where dep_id in 
        (select id from department where name=‘技術‘);

#查看不足1人的部門名
select name from department
    where id in 
        (select dep_id from employee group by dep_id having count(id) <=1);
技術分享圖片

帶比較運算符的子查詢

技術分享圖片
#比較運算符:=、!=、>、>=、<、<=、<>
#查詢大於所有人平均年齡的員工名與年齡
mysql> select name,age from emp where age > (select avg(age) from emp);
+---------+------+
| name | age |
+---------+------+
| alex | 48 |
| wupeiqi | 38 |
+---------+------+
2 rows in set (0.00 sec)


#查詢大於部門內平均年齡的員工名、年齡
select t1.name,t1.age from emp t1
inner join 
(select dep_id,avg(age) avg_age from emp group by dep_id) t2
on t1.dep_id = t2.dep_id
where t1.age > t2.avg_age;
技術分享圖片

帶EXISTS關鍵字的子查詢

EXISTS關字鍵字表示存在。在使用EXISTS關鍵字時,內層查詢語句不返回查詢的記錄。
而是返回一個真假值。True或False
當返回True時,外層查詢語句將進行查詢;當返回值為False時,外層查詢語句不進行查詢

技術分享圖片
#department表中存在dept_id=203,Ture
mysql> select * from employee
    ->     where exists
    ->         (select id from department where id=200);
+----+------------+--------+------+--------+
| id | name       | sex    | age  | dep_id |
+----+------------+--------+------+--------+
|  1 | egon       | male   |   18 |    200 |
|  2 | alex       | female |   48 |    201 |
|  3 | wupeiqi    | male   |   38 |    201 |
|  4 | yuanhao    | female |   28 |    202 |
|  5 | liwenzhou  | male   |   18 |    200 |
|  6 | jingliyang | female |   18 |    204 |
+----+------------+--------+------+--------+

#department表中存在dept_id=205,False
mysql> select * from employee
    ->     where exists
    ->         (select id from department where id=204);
Empty set (0.00 sec)
技術分享圖片

約束條件

約束條件與數據類型的寬度一樣,都是可選參數

作用:用於保證數據的完整性和一致性
主要分為:

技術分享圖片
PRIMARY KEY (PK)    標識該字段為該表的主鍵,可以唯一的標識記錄
FOREIGN KEY (FK)    標識該字段為該表的外鍵
NOT NULL    標識該字段不能為空
UNIQUE KEY (UK)    標識該字段的值是唯一的
AUTO_INCREMENT    標識該字段的值自動增長(整數類型,而且為主鍵)
DEFAULT    為該字段設置默認值

UNSIGNED 無符號
ZEROFILL 使用0填充
技術分享圖片

not null與default

是否可空,null表示空,非字符串
not null - 不可空
null - 可空

默認值,創建列時可以指定默認值,當插入數據時如果未主動設置,則自動添加默認值
create table tb1(
nid int not null defalut 2,
num int not null
)

技術分享圖片 技術分享圖片
==================not null====================
mysql> create table t1(id int); #id字段默認可以插入空
mysql> desc t1;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id    | int(11) | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
mysql> insert into t1 values(); #可以插入空


mysql> create table t2(id int not null); #設置字段id不為空
mysql> desc t2;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id    | int(11) | NO   |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
mysql> insert into t2 values(); #不能插入空
ERROR 1364 (HY000): Field id‘ doesnt have a default value



==================default====================
#設置id字段有默認值後,則無論id字段是null還是not null,都可以插入空,插入空默認填入default指定的默認值
mysql> create table t3(id int default 1);
mysql> alter table t3 modify id int not null default 1;
技術分享圖片

unique

技術分享圖片
============設置唯一約束 UNIQUE===============
方法一:
create table department1(
id int,
name varchar(20) unique,
comment varchar(100)
);


方法二:
create table department2(
id int,
name varchar(20),
comment varchar(100),
constraint uk_name unique(name)
);


mysql> insert into department1 values(1,‘IT‘,‘技術‘);
Query OK, 1 row affected (0.00 sec)
mysql> insert into department1 values(1,‘IT‘,‘技術‘);
ERROR 1062 (23000): Duplicate entry ‘IT‘ for key ‘name‘
技術分享圖片 技術分享圖片 技術分享圖片
create table service(
id int primary key auto_increment,
name varchar(20),
host varchar(15) not null,
port int not null,
unique(host,port) #聯合唯一
);

mysql> insert into service values
    -> (1,nginx‘,192.168.0.10‘,80),
    -> (2,haproxy‘,192.168.0.20‘,80),
    -> (3,mysql‘,192.168.0.30‘,3306)
    -> ;
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> insert into service(name,host,port) values(nginx‘,192.168.0.10‘,80);
ERROR 1062 (23000): Duplicate entry 192.168.0.10-80for key host
技術分享圖片

當一個字段被設置為not null和unique時,默認為主鍵

primary key

primary key字段的值不為空且唯一

一個表中可以:

單列做主鍵
多列做主鍵(復合主鍵)

但一個表內只能有一個主鍵primary key

技術分享圖片 技術分享圖片
============單列做主鍵===============
#方法一:not null+unique
create table department1(
id int not null unique, #主鍵
name varchar(20) not null unique,
comment varchar(100)
);

mysql> desc department1;
+---------+--------------+------+-----+---------+-------+
| Field   | Type         | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+-------+
| id      | int(11)      | NO   | PRI | NULL    |       |
| name    | varchar(20)  | NO   | UNI | NULL    |       |
| comment | varchar(100) | YES  |     | NULL    |       |
+---------+--------------+------+-----+---------+-------+
rows in set (0.01 sec)

#方法二:在某一個字段後用primary key
create table department2(
id int primary key, #主鍵
name varchar(20),
comment varchar(100)
);

mysql> desc department2;
+---------+--------------+------+-----+---------+-------+
| Field   | Type         | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+-------+
| id      | int(11)      | NO   | PRI | NULL    |       |
| name    | varchar(20)  | YES  |     | NULL    |       |
| comment | varchar(100) | YES  |     | NULL    |       |
+---------+--------------+------+-----+---------+-------+
rows in set (0.00 sec)

#方法三:在所有字段後單獨定義primary key
create table department3(
id int,
name varchar(20),
comment varchar(100),
constraint pk_name primary key(id); #創建主鍵並為其命名pk_name

mysql> desc department3;
+---------+--------------+------+-----+---------+-------+
| Field   | Type         | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+-------+
| id      | int(11)      | NO   | PRI | NULL    |       |
| name    | varchar(20)  | YES  |     | NULL    |       |
| comment | varchar(100) | YES  |     | NULL    |       |
+---------+--------------+------+-----+---------+-------+
rows in set (0.01 sec)
技術分享圖片 技術分享圖片 技術分享圖片
==================多列做主鍵================
create table service(
ip varchar(15),
port char(5),
service_name varchar(10) not null,
primary key(ip,port)
);


mysql> desc service;
+--------------+-------------+------+-----+---------+-------+
| Field        | Type        | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+-------+
| ip           | varchar(15) | NO   | PRI | NULL    |       |
| port         | char(5)     | NO   | PRI | NULL    |       |
| service_name | varchar(10) | NO   |     | NULL    |       |
+--------------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

mysql> insert into service values
    -> (172.16.45.10‘,3306‘,mysqld),
    -> (172.16.45.11‘,3306‘,mariadb)
    -> ;
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> insert into service values (172.16.45.10‘,3306‘,nginx);
ERROR 1062 (23000): Duplicate entry 172.16.45.10-3306for key PRIMARY
技術分享圖片
//alter刪除主鍵約束
alter table t3 drop primary key;
//alter添加主鍵約束
alter table t3 add primary key(name, pwd);
//alter 修改列為主鍵
alter table t3 modify id int primary key;

auto_increment

約束字段為自動增長,被約束的字段必須同時被key約束

技術分享圖片 技術分享圖片
#不指定id,則自動增長
create table student(
id int primary key auto_increment,
name varchar(20),
sex enum(male‘,female‘) default male
);

mysql> desc student;
+-------+-----------------------+------+-----+---------+----------------+
| Field | Type                  | Null | Key | Default | Extra          |
+-------+-----------------------+------+-----+---------+----------------+
| id    | int(11)               | NO   | PRI | NULL    | auto_increment |
| name  | varchar(20)           | YES  |     | NULL    |                |
| sex   | enum(male‘,female‘) | YES  |     | male    |                |
+-------+-----------------------+------+-----+---------+----------------+
mysql> insert into student(name) values
    -> (egon),
    -> (alex)
    -> ;

mysql> select * from student;
+----+------+------+
| id | name | sex  |
+----+------+------+
|  1 | egon | male |
|  2 | alex | male |
+----+------+------+


#也可以指定id
mysql> insert into student values(4,asb‘,female);
Query OK, 1 row affected (0.00 sec)

mysql> insert into student values(7,wsb‘,female);
Query OK, 1 row affected (0.00 sec)

mysql> select * from student;
+----+------+--------+
| id | name | sex    |
+----+------+--------+
|  1 | egon | male   |
|  2 | alex | male   |
|  4 | asb  | female |
|  7 | wsb  | female |
+----+------+--------+


#對於自增的字段,在用delete刪除後,再插入值,該字段仍按照刪除前的位置繼續增長
mysql> delete from student;
Query OK, 4 rows affected (0.00 sec)

mysql> select * from student;
Empty set (0.00 sec)

mysql> insert into student(name) values(ysb);
mysql> select * from student;
+----+------+------+
| id | name | sex  |
+----+------+------+
|  8 | ysb  | male |
+----+------+------+

#應該用truncate清空表,比起delete一條一條地刪除記錄,truncate是直接清空表,在刪除大表時用它
mysql> truncate student;
Query OK, 0 rows affected (0.01 sec)

mysql> insert into student(name) values(egon);
Query OK, 1 row affected (0.01 sec)

mysql> select * from student;
+----+------+------+
| id | name | sex  |
+----+------+------+
|  1 | egon | male |
+----+------+------+
1 row in set (0.00 sec)
技術分享圖片 技術分享圖片步長increment與起始偏移量offset:auto_increment_increment,auto_increment_offset

foreign key

員工信息表有三個字段:工號 姓名 部門

公司有3個部門,但是有1個億的員工,那意味著部門這個字段需要重復存儲,部門名字越長,越浪費

解決方法:

我們完全可以定義一個部門表

然後讓員工信息表關聯該表,如何關聯,即foreign key

技術分享圖片 技術分享圖片
#表類型必須是innodb存儲引擎,且被關聯的字段,即references指定的另外一個表的字段,必須保證唯一
create table department(
id int primary key,
name varchar(20) not null
)engine=innodb;

#dpt_id外鍵,關聯父表(department主鍵id),同步更新,同步刪除
create table employee(
id int primary key,
name varchar(20) not null,
dpt_id int,
constraint fk_name foreign key(dpt_id)
references department(id)
on delete cascade
on update cascade 
)engine=innodb;


#先往父表department中插入記錄
insert into department values
(1,歐德博愛技術有限事業部),
(2,艾利克斯人力資源部),
(3,銷售部);


#再往子表employee中插入記錄
insert into employee values
(1,egon‘,1),
(2,alex1‘,2),
(3,alex2‘,2),
(4,alex3‘,2),
(5,李坦克‘,3),
(6,劉飛機‘,3),
(7,張火箭‘,3),
(8,林子彈‘,3),
(9,加特林‘,3)
;


#刪父表department,子表employee中對應的記錄跟著刪
mysql> delete from department where id=3;
mysql> select * from employee;
+----+-------+--------+
| id | name  | dpt_id |
+----+-------+--------+
|  1 | egon  |      1 |
|  2 | alex1 |      2 |
|  3 | alex2 |      2 |
|  4 | alex3 |      2 |
+----+-------+--------+


#更新父表department,子表employee中對應的記錄跟著改
mysql> update department set id=22222 where id=2;
mysql> select * from employee;
+----+-------+--------+
| id | name  | dpt_id |
+----+-------+--------+
|  1 | egon  |      1 |
|  3 | alex2 |  22222 |
|  4 | alex3 |  22222 |
|  5 | alex1 |  22222 |
+----+-------+--------+
技術分享圖片

兩張表之間的關系

技術分享圖片
分析步驟:
#1、先站在左表的角度去找
是否左表的多條記錄可以對應右表的一條記錄,如果是,則證明左表的一個字段foreign key 右表一個字段(通常是id)

#2、再站在右表的角度去找
是否右表的多條記錄可以對應左表的一條記錄,如果是,則證明右表的一個字段foreign key 左表一個字段(通常是id)

#3、總結:
#多對一:
如果只有步驟1成立,則是左表多對一右表
如果只有步驟2成立,則是右表多對一左表

#多對多
如果步驟1和2同時成立,則證明這兩張表時一個雙向的多對一,即多對多,需要定義一個這兩張表的關系表來專門存放二者的關系

#一對一:
如果1和2都不成立,而是左表的一條記錄唯一對應右表的一條記錄,反之亦然。這種情況很簡單,就是在左表foreign key右表的基礎上,將左表的外鍵字段設置成unique即可
技術分享圖片

數據庫設計

1.概念
1.有效存儲數據
2.滿足用戶的多種需求

2.關系
1-1 :最少需要1張表
1-n :最少需要2張表
n-n :最少需要3張表

3.數據庫三範式
1.保證每列的原子性
2.保證每列都與主鍵相關
3.保證每列都和主鍵直接相關,而不能是間接相關
三範式的詳解:http://www.cnblogs.com/wangfengming/p/7929118.html

索引

1.概念:相當於書的目錄,快速找到數據
好處:可以幫助你提高查詢效率,數據量越大越明顯
缺點: 新增和刪除數據時,效率較低
2.索引方法:
1.hash 是以key-value 的形式進行索引存儲
2.BTree 是以二叉樹方式進行索引存儲。(默認存儲索引類型)
3.索引分類
1. 普通索引 create INDEX name_index on person(name);
2. 唯一索引 create unique INDEX name_age on person(name,age);
3. 主鍵索引 alter table person MODIFY id int PRIMARY key;
4. 組合索引 create unique INDEX name_age on person(name,age);
5. 全文索引 full text :原理是分詞查找

創建 普通索引

CREATE index aaa on ren(p_name)
添加普通索引
註意:index :表示索引 aaa:表示索引的別名, on:表示給哪個表添加索引  ren:表名稱,(添加索引的字段,多個字段以","間隔)

alter table ren add index aaa(p_name)

創建 唯一索引

CREATE UNIQUE index age on ren(p_age)
添加唯一索引
註意:unique index :表示唯一索引 aaa:表示索引的別名, on:表示給哪個表添加索引  ren:表名稱,(添加索引的字段,多個字段以","間隔)

創建 主鍵索引

alter table 表名 add primary key(id);
添加之間索引
註意:主鍵索引只能有一個

創建 組合索引

create index id_name on ren (id,name)
添加組合索引
註意: 如上創建組合索引之後,查詢:
id and name-- 使用索引
id                -- 使用索引
name           -- 不使用索引

數據庫 設計 和多表查詢