Mysql_DML(Mysql Data Manipulation Language數據操作語言)
插入數據:insert、replace
(1)使用values()或value():insert into tables_name values(),()…,();
(2)使用set語句:insert into table_name set column_name=value1,…;
(3)insert into table_name select_statement;
1.1 insert into values()
給定如下表結構:
create or replace table tbl1(
id int primary key,
sex char(3) default 'nv',
name varchar(20),
age int(4)
);
(1)insert into tbl_name values(),(),(),...();
(2)insert into select_statement
insert into tbl_name select 10,'nan','somthing';
insert into tbl_name select 11,'nan','somthing' from tbl_name2;
insert into tbl_name select 12,'nan','somthing' union select 13,'nan','something';
union用法:將多條語句結果合併成一個結果,如上面兩個select結果合併後變成一個結果傳遞給tbl_name,那麼就相當於一次性傳遞兩行了
通過select來檢索其他表的字段來插入數據:
insert into tbl_name select age,sex,name from student;
(3)insert into set
insert into tbl_name set name='something',id=10,sex='nan';
變量:autocommit=1
(1)當值爲1或on的時候,意味着innoDB表每次insert以及其他的DML操作都會自動提交事務,
提交事務意味着將會將髒讀數據刷到磁盤,影響插入效率
創建並插入數據:
(1)create table tbl_name select_statement;
(2)create table tbl_name as select_statement;
##新創建的表必須不存在,除非使用了or replace或者if not exist子句
示例:創建並插入數據:
(1)create table tbl_name select user,host, from mysql.user where user='root';
(2)insert into test(id,name,age,sex) select id,name,age,sex from student where name='lindaiyu' or name='jiabaoyu';
(3)create table test2(id int(8),name varchar(20),age int(8)) as select id,name,age from student; ###創建表並且將數據插入
(4)create table test2(id int(8),name varchar(20),age int(8)) as select id,name,age from student where false; ##創建表單數不插入數據
1.創建相同的表結構:會複製表的屬性
create table tbl_name like mysql.user;
2.創建表,指定幾個字段,但是不復製表的其他屬性
create table tbl_name as select_statement;
處理鍵值重複:
1.當表中存在唯一索引(如primary key,unique index)時,插入的記錄如果重複則會報錯,如下:
MariaDB [school]> insert into student set id=20190125,name=‘wenwen’,age=‘17’,sex=‘nv’;
ERROR 1062 (23000): Duplicate entry ‘20190125’ for key ‘PRIMARY’
處理方式:
1.使用ignore關鍵字忽略所有錯誤行,使用insert操作繼續插入後面的數據
2.使用insert…into on duplicate key update,將有重複行update爲新的值
3.使用replace into語句替代insert into,將有重複值的航替換爲新行
示例:
(1)insert ignore into student values('20190101','fangfang','19','nv');
##這條記錄其實沒有插入成功,被忽略掉了,所以沒有報錯,只是告警了一下
MariaDB [school]> insert ignore into student values('20190101','fangfang','19','nv');
Query OK, 0 rows affected, 1 warning (0.00 sec)
(2)insert into student values('20190101','fangfang','29','nv') on duplicate key update name='fangfang1';
##這個表示如果此記錄與原表中某個行衝突,那麼就只修改此行中的name,其他的列不作修改。如果沒有衝突的話就直接將此行插入就行了。
(3)replace into student values('20190101','wenwen','17','nv');
##這個就是如果主鍵與原紀錄衝突的話那麼直接覆蓋原紀錄
數據導入導出:
語句:load data infile和select into outfile語句是配套的。
1.導出數據:select into outfile語句是將檢索出來的數據按格式導出到文件中,跨數據庫系統遷移時,該項很有用,可以指定分隔符。
2.導入數據:load data infile是將導入的數據文件導入到表中
變量:secure_file_priv
(1)值爲null時,它表示禁用以上兩語句的導出導入
(2)不設置值時,對以上兩語句不產生限制
(3)/path/to/dir只允許該目錄內 select…into outfile和load data infile
注意:mysql系統用戶和組需要對該目錄擁有讀寫權限
變量修改:靜態全局變量,因此需要先停止mysql服務,修改配置文件後再啓動生效
[mysqld]
secure-file-priv=/data
##或者不設置任何值,直接註釋掉就好
#secure-file-priv=
變量查看:
select @@global.secure_file_priv;##可以查看到授權的文件夾
語法:
SELECT ... INTO OUTFILE 'file_name'
[CHARACTER SET charset_name]
[export_options]
LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name'
[REPLACE | IGNORE]
INTO TABLE tbl_name
[CHARACTER SET charset_name]
[export_options]
[IGNORE number {LINES|ROWS}]
[(col_name_or_user_var,...)]
[SET col_name = expr,...]
導出數據:
select * from tbl_name into outfile ‘/path/to/somefile.sql’;
導入數據:高級用法暫時不作記錄
load data infile ‘/path/to/somefile.sql’ into table test.t
mysqldump導出數據:導出表結構和數據
示例:mysqldump -h 192.168.99.11 -uroot -p123456 -P3306 testdb > test.sql;
mysqlimport導入數據:
mysqlimport [OPTIONS] database_name textfile…
指定兩個線程,導入兩張表到數據庫test庫中的t1和t2表中。
mysqlimport -uroot -p123456 --use-threads=2 --fields-terminated-by=',' test '/data/t1.txt' '/data/t2.txt'
數據更新語句:
update語句:update [LOW_PRIORITY] [IGNORE] table_reference
[PARTITION (partition_list)]
SET col1={expr1|DEFAULT} [,col2={expr2|DEFAULT}] …
[WHERE where_condition]
[ORDER BY …]
[LIMIT row_count]
update tbl_name set col=value where colm2=value2;##通用語句
數據刪除語句:
delete語句:DELETE [LOW_PRIORITY] [QUICK] [IGNORE]
FROM tbl_name [PARTITION (partition_list)]
[WHERE where_condition]
[ORDER BY …]
[LIMIT row_count]
[RETURNING select_expr
[, select_expr …]]
delete from t where id>6 and sex=‘nv’;
delete from t order by id limit 2;
開窗函數:
排名函數:ROW_NUMBER(),RANK(),DESC_RANK(),PERCENT_RANK(),CUME_DIST(),NTILE()
聚合函數:COUNT(),SUM(),AVG(),BIT_OR(),BIT_AND(),BIT_XOR()
不支持帶有DISTINCT的聚合函數,例如COUNT(DISTINCT X)
PARTITION BY子句用於劃分窗口,也就是另類的GROUP BY。
ORDER BY子句用於對分區內的進行排序。
1.示例:使用row_number()函數對分區進行排名
create table tscore(
sid int,
subject char(10),
score int
);
insert into tscore values(
(1,'Java',74),(1,'Linux',67),(1,'SQL',57),
(2,'Java',67),(2,'Linux',63),(2,'SQL',68),
(3,'Java',90),(3,'Linux',79),(3,'SQL',82),
(4,'Java',50),(4,'Linux',68),(4,'SQL',59),
(5,'Java',98),(5,'Linux',65),(5,'SQL',67),
(6,'Java',66),(6,'Linux',96),(6,'SQL',95);
);
權限管理:
1.grant select on dbname.* to ‘root’@‘localhost’,‘xjw’@‘localhost’;
2.grant select(name,host) on mysql.user to 'root'@'localhost';
#授權用戶對mysql.user表的name和host字段擁有select權限
3.grant execute on function mysql.test to 'root'@'localhost';
#通過關鍵字function來對函數進行授權
grant select on mysql.test to 'root'@'localhost';
4.procedure關鍵字,表明對存儲過程進行授權
grant execute on procedure mysql.test to 'root'@'locahost';
5.登錄權限:usage
grant usage on *.* to 'root'@'IP' require ssl;
##當用戶可能通過跨越不安全的網絡連接到數據庫時,則可以通過此句來要求用戶使用ssl連接
6.grant usage on *.* to 'root'@'IP' require none;
7.使用戶能夠有授權其他用戶的權限
grant select on mysql.user to 'root'@'localhost' with grant option;
# 不建議這樣授權,以免後期權限難以管理
用戶限制:用法類似於上面的 with grant option
1.MAX_QUERIES_PER_HOUR:限制用戶每小時的查詢數量
2.MAX_UPDATE_PER_HOUR:限制用戶每小時更新語句數量
3.MAX_CONNECTIONS_PER_HOUR:限制用用戶每小時連接數據庫的次數
4.MAX_USER_CONNECTIONS:限制用戶使用當前賬號同時連接數據庫的連接數量
示例:
grant select on *.* to 'root'@'localhot' with max_queries_per_hour 10;
查看授權:
show grant for 用戶名;
show grant for 'root'@'localhost';
刪除授權:
revoke “select,drop” on mysql.user from ‘root’@‘localhost’;
##從某個用戶那裏刪除在mysql.user上的select和drop權限
revoke all on mysql.* from 'root'@'localhost';
外鍵:create table test1 (id int primary key,name varchar(20) not null,tid int,foreign key(tid) references test2(id));
##表test1的tid引用表test2的id位外鍵
索引:create table test1(id int,name varchar(16) not null,primary key(id),index ind_name(name));
添加索引:alter table tbl_name add index index_name(colum1,colum2,..);
刪除索引:alter table tbl_name drop index index_name;
創建表並插入數據:create table test1 select * from student limit 10;
附帶engine的建表語句:
create table tbl_name(
id int primary key auto_increment,
name varchar(20) not null,
index ind_name(name)
)
engine=InnoDB auto_increment=2 default charset=utf-8;
修改表的基本語法:
alter table tbl_name [alter_sprcification …]
1.表格重命名
alter table test1 rename as test2;
2.添加字段
alter table test1 add column col_name1 varchar(16) first;
alter table test1 add column col_name2 varchar(16) not null default 'string' after col_name1;
刪除:alter test1 drop column col_name;
3.字段重命名,仍然需要指定原字段數據類型
alter table test1 change old_col_name new_col_name varchar(16);
4.修改字段數據類型,不能用於修改字段名,同時如果該字段爲索引的話,那麼字段數據長度不能修改到小於索引長度
alter table test1 modify col_name1 char(16);
5.非空約束
alter table test1 modify col_name1 varchar(100) not null;
刪除非空約束
alter table test1 modify col_name1 varchar(100) null;
6.自動增長
alter table test1 modify col_name1 int(100) auto_increment;
alter table test1 change col_name1 int(100) auto_increment;
刪除自動增長:
alter table test1 modify col_name1 int(100);
alter table test1 change col_name1 int(100);
7.主鍵約束
alter table test1 add primary key(id);
alter table test1 add constraint primary key(id);
刪除主鍵(若主鍵帶有自動增長屬性,需要先刪除自動增長屬性)
alter table test1 modify id int(100) auto_increment;
alter table test1 drop primary key;
8.唯一鍵約束:alter table tbl_name add unique key uniq_name(col_name);
刪除唯一鍵:alter table tbl_name drop index uniq_name;##需要使用index關鍵字
select以及與正則表達式結合的運用:
1.取非
select * from user where age != 28;
2.取範圍
select * from user where age >=18 and age <=38;
select * from user where age between 18 and 38;
3.取或
select * from user where age = 18 or age = 28;
4.取補集
select * from user where age not between 18 and 38;
select * from user where age < 18 or age > 38;
select與正則表達式的運用:
1.select * from user where name like 'J%'; ###%表示任意長度的任意字符
2.select * from user where name like 'J__';###_表示任意一個字符
3.select * from user where name rlike '^t.*'; ###與rlike匹配,表示以字母t開頭的所有用戶
4.select * from user where age in (10,20,30,40);
取反:select * from user where age not in (10,20,30,40);
排序:
1.select * from user order by age asc; ###表示升序排列,默認asc可省略
2.select * from user order by age desc; ###表示降序排列
3.select * from tb1 order by age desc,name asc; ###先按照年齡降序排列,若年齡相同則按名稱升序排列
去重:distinct
1.select distinct name from student; ##選取年齡列,並且去重顯示
別名:as
1.select name as stu_name,age from student; ##選取name和age列,並且將name列取別名顯示
擴展:select name as stu_name,age as stu_age from student;
聚合函數:
MariaDB [school]> select name,avg(age),sex from student group by sex;
+--------+----------+-----+
| name | avg(age) | sex |
+--------+----------+-----+
| jiajia | 39.5000 | nan |
| wenwen | 96.4211 | nv |
+--------+----------+-----+
2 rows in set (0.03 sec)
分組後再次過濾:having
select avg(age) as avgage,name,sex from student group by sex having avgage > 50;
MariaDB [school]> select avg(age) as avgage,name,sex from student group by sex having avgage > 50;
+---------+--------+-----+
| avgage | name | sex |
+---------+--------+-----+
| 96.4211 | wenwen | nv |
+---------+--------+-----+
1 row in set (0.00 sec)
1.min(col):返回該列最小值
2.max(col):返回該列最大值
3.avg(col):返回該列平均值
4.count(col):返回該列中非NUll值的個數
5.sum(col):返回該列所有值之和
6.group_concat(col):返回指定列的值,並且是分組顯示
多表查詢:
1.交叉連接
select * from tbl_name1.tbl_name2;
select * from tbl_name1 cross join tbl_name2;
2.內連接
select * from tbl_name1,tbl_name2 where tbl_name1.col1=tbl_name2.col1
select * from tbl_name1 inner join tbl_name2 on tbl_name1.col1=tbl_name2.col1;
3.自連接
select * from student s1 inner join student s2 on s1.age=s2.id;
##其實就是將指定的兩個字段值相同的行取出來再進行cross join就行了