內容目錄
- 庫的增刪改查
- 表的增刪改查
強調:講解內容以5.7版本為例
1 庫的增刪改查
這里的庫指的數據庫,也就是我們所謂的那個文件夾,一般情況下,我們在開發項目前,會先設計數據庫中相關表結構,一個項目中所有表都會放在同一個文件夾下,對於庫的操作屬於SQL分類中的DDL,也就是數據庫定義語言。
1.1 創建數據庫
# 創建數據庫並制定編碼 create database 庫名 charset 字符編碼 create database db1 charset utf8; # 不指定字符編碼 create database db1; # 使用數據庫 use 庫名 use db1; # 查看當前庫 select database();
1.2 查詢數據庫
# 查看所有的數據庫 show databases; # 查看其中一個數據庫 show create database 庫名 show create database db1; # 查看數據庫編碼 show variables like '%char%'
1.3 修改數據庫
數據庫的名稱一旦創建好之后就無法修改
# 修改數據庫一般只修改編碼 alter database 庫名 charset 字符編碼 alter database db1 charset utf8;
1.4 刪除數據庫
drop database 庫名 drop database db1;
相信很多人做數據的同行,看到這些之后會說,這些語句都沒啥用,我在工作中很少用,一般使用Navicate就可以通過菜單實現,說的沒錯,對於數據分析而言,我們不需要像程序員那樣全程使用終端徒手敲代碼,我們完全可以使用可視化工具來通過菜單的右擊操作實現,上節課我們已經引入了Navicate,那接下來我就演示一下如何使用它操作數據庫。

ps:是不是很簡單,但是我個人還是喜歡在終端使用命令實現,接下來,我再演示一下在終端如何操作。

2 表的增刪改查
2.1創建表
create table 表名(
字段名1 類型(寬度) 約束條件,
字段名2 類型(寬度) 約束條件,
字段名3 類型(寬度) 約束條件,
);
注意:
1.字段名不能重復
2.寬度和約束條件可選
3.字段名和類型是必須的
查看表結構
1.兩種查看表結構的方式
desc 表名; # describe 表名 二者是一樣的
show create table 表名; # show create table 表名 \G
數據庫(文件夾)中包含多張表,跟Excel的表很像,但是它包含了兩部分,一部分是表結構,一部分是表數據。
我們先看一下數據庫中的表長什么樣子?
表數據

表結構

之前學過SPSS的同學若沒有學過,點擊這里 https://zhuanlan.zhihu.com/p/123845239
我們知道SPSS也有自己的數據表結構,叫做視圖
對於上述內容,大家肯定不太理解數據類型和約束條件這部分,下面就詳細展開講一下
2.2 數據類型
2.1.1字符串
顧名思義,就是存儲的一連串的字符,例如文字

我們主要用到的是char和varchar這兩種字符串類型,二者的區別是面試經常考的內容
區別1:定長和變長
char 固定長度,例如你定義了char(8),則這一列中存儲的內容長度都為8,不足8則會用空格補充(但是我們在查詢的時候是不會帶空格的,mysql會對此進行處理)
varchar 變長存儲,則根據實際的字符長度存儲,例如varchar(8),則不足8按照實際存儲,
ps: 對於上述兩個類型,如果超過8則會根據你設置的sql_mode而定,默認是【| NO_ENGINESUBSTITUTION】-非嚴格模式,這種情況下,超過8會被截斷;如果你的sql_mode是 【strict_trans_tables】則超過8會報錯

那就借此補充一下如何修改sql_mode
# 查看模式 show variables like '%mode%' 默認是非嚴格模式 +----------------------------+------------------------+ | Variable_name | Value | +----------------------------+------------------------+ | binlogging_impossible_mode | IGNORE_ERROR | | block_encryption_mode | aes-128-ecb | | gtid_mode | OFF | | innodb_autoinc_lock_mode | 1 | | innodb_strict_mode | OFF | | pseudo_slave_mode | OFF | | slave_exec_mode | STRICT | | sql_mode | NO_ENGINE_SUBSTITUTION | +----------------------------+------------------------+ # 修改成嚴格模式 set global sql_mode="strict_trans_tables"; 改完之后需要退出重登 # 顯示實際長度(字符串中char類型自動去掉空格) set global sql_mode="strict_trans_tables,pad_char_to_full_length"
區別2:存儲方式
char直接存儲字符內容
varchar 開頭由1-2個字節存儲該字符的總長度,后面接着存儲字符內容
總結:char的存取速度很快,但是由於是定長,當大部分內容沒有達到規定長度時,會浪費不少空間資源;varchar則不會,它根據實際長度存儲,但是由於存儲的特殊形式造成存取速度不及char,當char存儲的內容都為一個定值時,則char不僅不浪費空間還提高存取效果,因為varchar還要留出一部分存儲字符串的長度。很早之前,大家都覺得varchar好,節省資源,但是到現在,磁盤資源已經不成問題,因此我更傾向於選擇char,也就是所謂的以空間換時間了。
2.1.2數值型
常用的有:int double float decimal


整數型:int 基本int能夠處理日常工作中大部分整數存儲問題
小數型:double float decimal
下面通過例子來分析一下三者的區別
設置數據類型的長度約束
# 創建表num,三個字段分別設置為三個不同數據類型,強調一下float(5,2) 其中5代表總長度,2代表小數長度,這個意思是整數是3位,小數是2位 create table num(num1 float(5,2),double(5,2),decimal(5,2)); # 插入一條數據 insert into num(1.234,1.234,1.234); # 結果 mysql> select * from num; +------+------+------+ | num1 | num2 | num3 | +------+------+------+ | 1.23 | 1.23 | 1.23 | +------+------+------+ 1 row in set (0.00 sec)
三者都會根據數據類型設置的長度進行四舍五入的數據顯示
若都使用默認值,不設置條件
alter table num modify num1 float; alter table num modify num2 double; alter table num modify num3 decimal; insert into num values(1.232323232323232,1.232323232323232,1.232323232323232); mysql> select * from num; +---------+-------------------+------+ | num1 | num2 | num3 | +---------+-------------------+------+ | 1.23 | 1.23 | 1 | | 1.23 | 1.23 | 1 | | 1.23232 | 1.232323232323232 | 1 | +---------+-------------------+------+ 3 rows in set (0.00 sec)
我們可以看出,如果使用默認值,則double比float顯示的更精確,而decimal則默認以decimal(10,0)來顯示,因此會是整數。
並且,decimal是定點型,默認存儲的是字符串格式,double和float屬於浮點型
日常工作中float足以解決小數問題了。
2.1.3 日期型

舉例說明
create table t(date1 date,time,datetime);
insert into t(now(),now(),now());
mysql> select * from t;
+------------+----------+---------------------+
| date1 | date2 | date3 |
+------------+----------+---------------------+
| 2020-04-15 | 16:02:43 | 2020-04-15 16:02:43 |
+------------+----------+---------------------+
1 row in set (0.00 sec)
2.1.4 ENUM和SET類型

這里的類似於下拉字段,在進行數據插入的時候,必須選擇事先設置的內容
create table t1(id int,name char(6),gender enum('female','male'),hobby set('抽煙','喝酒','燙頭'));
insert into t1 values(1,'張三','男','喝酒');
insert into t1 values(1,'張三','female','喝酒');
mysql> select * from t1;
+------+--------+--------+--------+
| id | name | gender | hobby |
+------+--------+--------+--------+
| 1 | 張三 | | 喝酒 |
| 1 | 張三 | female | 喝酒 |
+------+--------+--------+--------+
2 rows in set (0.00 sec)
# 男不屬於enum的枚舉內容,因此不顯示
對於set而言,可以多選,但是enum只能單選
mysql> insert into t1 values(1,'張三','男','喝酒,燙頭');
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> select * from t1;
+------+--------+--------+---------------+
| id | name | gender | hobby |
+------+--------+--------+---------------+
| 1 | 張三 | | 喝酒 |
| 1 | 張三 | female | 喝酒 |
| 1 | 張三 | | 喝酒,燙頭 |
+------+--------+--------+---------------+
3 rows in set (0.00 sec)
2.3 約束條件
為了防止不符合規范的數據進入數據庫,在用戶對數據進行插入、修改、刪除等操作時,DBMS自動按照一定的約束條件對數據進行監測,使不符合規范的數據不能進入數據庫,以確保數據庫中存儲的數據正確、有效、相容。
約束條件與數據類型的寬度一樣,都是可選參數,主要分為以下幾種:
NOT NULL :非空約束,指定某列不能為空;
UNIQUE : 唯一約束,指定某列或者幾列組合不能重復
PRIMARY KEY :主鍵,指定該列的值可以唯一地標識該列記錄
FOREIGN KEY :外鍵,指定該行記錄從屬於主表中的一條記錄,主要用於參照完整性
2.3.1 not null
不為空,當你設置一個字段時,不允許它為空,可以使用此約束條件
create table t3(id int not null);
insert into t3 values(1);
default 默認值
例如:對於性別一列,如果大部分都是男性,可以設置成默認值,不填則取默認值,填寫了則覆蓋默認值
alter table t3 add sex default "female";
# 創建時也可以使用默認值,create table t5(id int,sex char(6) not null default "female");
insert into t3(id) values(1);
insert into t3(id) values(2,"male");
mysql> select * from t3;
+----+--------+
| id | sex |
+----+--------+
| 0 | female |
| 0 | female |
| 1 | female |
| 2 | male |
+----+--------+
4 rows in set (0.00 sec)
2.3.2 unique 唯一
當有一列字段你不想讓它有重復值時,可以設置為唯一
單字段設置唯一約束
# 方法1
create table t4(id int not null,name char(8) unique);
# 方法2
create table t4(id int not null,name char(8),unique(name));
mysql> create table t4(id int not null,name char(8) unique);
Query OK, 0 rows affected (0.02 sec)
mysql> insert into t4 values(1,"張三");
Query OK, 1 row affected (0.00 sec)
mysql> insert into t4 values(1,"張三");
ERROR 1062 (23000): Duplicate entry '張三' for key 'name'
mysql> select * from t4;
+----+--------+
| id | name |
+----+--------+
| 1 | 張三 |
+----+--------+
1 row in set (0.00 sec)
聯合唯一
只有當你設置的這些字段同時重復時才會報錯
create table t6(id int,name char(6),depment char(10),unique(name,depment));
mysql> insert into t6 values(1,"張三","咨詢部");
Query OK, 1 row affected (0.01 sec)
mysql> insert into t6 values(1,"李四","咨詢部");
Query OK, 1 row affected (0.01 sec)
mysql> insert into t6 values(1,"張三","咨詢部");
ERROR 1062 (23000): Duplicate entry '張三-咨詢部' for key 'name'
mysql> select * from t6;
+------+--------+-----------+
| id | name | depment |
+------+--------+-----------+
| 1 | 張三 | 咨詢部 |
| 1 | 李四 | 咨詢部 |
+------+--------+-----------+
2 rows in set (0.00 sec)
2.3.3 primary key
主鍵為了保證表中的每一條數據的該字段都是表格中的唯一值。換言之,它是用來獨一無二地確認一個表格中的每一行數據。
主鍵可以包含一個字段或多個字段。當主鍵包含多個欄位時,稱為組合鍵 (Composite Key),也可以叫聯合主鍵。
主鍵可以在建置新表格時設定 (運用 CREATE TABLE 語句),或是以改變現有的表格架構方式設定 (運用 ALTER TABLE)。
主鍵必須唯一,主鍵值非空;可以是單一字段,也可以是多字段組合。
單字段主鍵
mysql> create table t7(id int primary key,name char(6));
Query OK, 0 rows affected (0.02 sec)
mysql> insert into t7 values(1,"wanger");
Query OK, 1 row affected (0.00 sec)
mysql> insert into t7 values(1,"wang");
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
mysql> select * from t7;
+----+--------+
| id | name |
+----+--------+
| 1 | wanger |
+----+--------+
1 row in set (0.00 sec)
聯合主鍵
mysql> create table t8(id int,name char(8),primary key(id,name));
Query OK, 0 rows affected (0.02 sec)
mysql> insert into t8 values(1,'zhang');
Query OK, 1 row affected (0.01 sec)
mysql> insert into t8 values(2,'zhang');
Query OK, 1 row affected (0.01 sec)
mysql> insert into t8 values(2,'zhang');
ERROR 1062 (23000): Duplicate entry '2-zhang' for key 'PRIMARY'
mysql> select * from t8;
+----+-------+
| id | name |
+----+-------+
| 1 | zhang |
| 2 | zhang |
+----+-------+
2 rows in set (0.00 sec)
了解內容
auto_increment 自增字段,對於id而言,往往我們可以設置為自增字段,不用手動填寫
mysql> create table t9(id int primary key auto_increment,name char(6));
Query OK, 0 rows affected (0.04 sec)
mysql> insert into t9(name) values ("張三"),("李四"),("王五");
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * from t9;
+----+--------+
| id | name |
+----+--------+
| 1 | 張三 |
| 2 | 李四 |
| 3 | 王五 |
+----+--------+
3 rows in set (0.00 sec)
2.3.4 foreign key
多表 :
假設我們要描述所有公司的員工,需要描述的屬性有這些 : 工號 姓名 部門
公司有3個部門,但是有1個億的員工,那意味着部門這個字段需要重復存儲,部門名字越長,越浪費
解決方法: 我們完全可以定義一個部門表 然后讓員工信息表關聯該表,如何關聯,即foreign key
前提條件:#
類型必須是innodb存儲引擎,且被關聯的字段,即references指定的另外一個表的字段,必須保證唯一
# 首先創建部門表 mysql> create table depment1(id int primary key,name char(10) not null); Query OK, 0 rows affected (0.02 sec) # 創建用戶表並關聯部門表 mysql> create table empment(id int primary key auto_increment,name char(6),dep_id int, foreign key(dep_id) references depment1(id)); Query OK, 0 rows affected (0.02 sec)
級聯刪除,級聯更新
兩張表建立關聯之后,如果部門表某個部門的砍掉了,那對應的人員表中的那些部門的人員相應的該怎么處理呢?可以保存,也可以隨之一起刪除
如果要保證兩表一致,則需要在設置外鍵時添加on delete cascade
如果部門id更新了,要一起更新的話,則添加on update cascade
舉個例子
mysql> create table depment2(id int primary key,name char(10) not null); Query OK, 0 rows affected (0.02 sec) mysql> create table empment2(id int primary key auto_increment,name char(6),dep_id int, foreign key(dep_id) references depment1(id) on delete cascade on update cascade); Query OK, 0 rows affected (0.03 sec)
2.4 修改表
# 創建庫 create database db4; # 創建表 create table dep( id int primary key auto_increment, name char(16) not null, age int, gender enum("male","female") ); # 1.修改表名 alter table 舊表名 rename 新表名 alter table dep rename dep_new; # 修改表字段的數據類型 alter table 表名 modify 字段 新數據類型 alter table dep modify name varchar(16); # 修改表字段 alter table 表名 change 字段 舊數據類型 [約束條件] alter table dep_new change name new_name varchar(10); # 修改表字段及數據類型 alter table 表名 change 字段 新數據類型 [約束條件] alter table dep_new change new_name name char(16) not null; # 新增表字段 alter table 表名 add 字段名 數據類型 [完整性約束條件], add 字段名 數據類型 [完整性約束條件]; alter table dep_new add class char(10) not null; # 指定位置添加字段 # 添加到首位 alter table 表名 add 字段名 數據類型 [完整性約束條件] first alter table dep_new add my_id int not null first; # 添加到中間的某個位置 alter table 表名 add 字段名 數據類型 [約束條件] after 字段名 alter table dep_new add my_name char(10) not null after name; alter table dep_new change my_name new_name varchar(18) not null first; alter table dep_new modify new_name varchar(18) not null after id; # 修改約束條件 外鍵 2.單獨增加外鍵 # 添加外鍵字段 alter table dep_new add dep_id int; # 添加外鍵關系[指定外鍵名稱] alter table dep_new add constriant fk_dep_id foreign key(dep_id