1. 程式人生 > 資料庫 >mysql資料庫學習

mysql資料庫學習

文章目錄

資料庫基礎語法

資料庫密碼修改

#第一種
mysqladmin -uroot -pxxx password 'xxx'

#第二種
mysql -uroot -p
mysql>set passowrd for root@'localhost'=password('xxxxx');

#第三種
mysql -uroot -p
mysql>alter user root@'localhost' identified by 'xxxxxx';

#修改密碼策略
mysql -uroot -p
mysql>set global validate_password_policy=0;   #修改密碼策略等級  
#0或LOW為只驗證密碼長度  
#1或MEDIUM驗證長度 數字 大小寫和特殊字元
#2或STRONG驗證長度 數字  大小寫和特殊字元 字典檔案
mysql>set global validate_password_length=6;   #修改密碼最短長度為6


#檢視資料庫變數
mysql -uroot -p
mysql> show variables like '%password%';    #檢索出含有password的變數
+---------------------------------------+-------+
| Variable_name                         | Value |
+---------------------------------------+-------+
| default_password_lifetime             | 0     |
| disconnect_on_expired_password        | ON    |
| log_builtin_as_identified_by_password | OFF   |
| mysql_native_password_proxy_users     | OFF   |
| old_passwords                         | 0     |
| report_password                       |       |
| sha256_password_proxy_users           | OFF   |
| validate_password_check_user_name     | OFF   |
| validate_password_dictionary_file     |       |
| validate_password_length              | 6     |
| validate_password_mixed_case_count    | 1     |
| validate_password_number_count        | 1     |
| validate_password_policy              | LOW   |
| validate_password_special_char_count  | 1     |
+---------------------------------------+-------+


#mysql密碼忘了  修改
vim /etc/my.cnf
=======================
[mysqld]
skip_grant_tables     #登入無需驗證密碼
#validate_password_policy=0
#validate_password_length=6                密碼策略相關的要註釋
=====================================
systemctl restart mysqld   #重啟服務

mysql #直接進入      直接更新mysql root使用者密碼
>update mysql.user set authentication_string=password('xxxxx')
->where user='root' and host='localhost';

>flush privileges;   #重新整理
>exit  #退出

vim /etc/my.cnf  #修改配置檔案回來
#重新登入



#也可以
mysql
flush privileges;  #先重新整理許可權 否則會告訴在skip_grant_tables中沒法修改
alter user root@'localhost' identified by 'xxxxxx';
exit

#修改配置檔案回來

三類語句

  • DDL 建立語句 (create、drop、alter)
  • DML 操作資料語句(insert、delete、update、select、truncate)
  • DCL 資料控制語句(grant、revoke)
  • DTL 資料事務語言 (commit、rollback、savepoint)

建立表

create table tablename(
column_name1  column_type1 constraints,
column_name2  column_type2 constraints
)
  • column_name1 列名
  • column_type1 列型別(varchar、date、int…)
  • constraints 約束條件

查詢表結構

use test;      #進入test表
create table emp(ename varchar(10), hiredate date, sal decimal(10,2),deptno int(2));
desc emp;        #查看錶emp結構
drop table emp; #刪除表emp

重命名錶名

語法

  • alter table tablename rename newtablename

  • 舉例

alter table emp rename emp2;           #修改表名
alter table emp2 rename emp;            #修改表名

alter table test.emp rename mydb.empcopy;  #複製到另一個數據庫中 

修改表字段定義

語法

  • alter table tablename modify[column] column_definition[first|after col_name]

after | first為mysql在基礎SQL上的擴充套件 不是每個資料庫語法都支援

  • 舉例
alter table emp modify ename varchar(20);  #修改表emp的ename列的資料型別為varchar(20)

增加表字段

語法

  • alter table tablename add[column] column_definition[first|after col_name]

  • 舉例

alter table emp add column age int(3);   #新增age列資料型別為int(3)

刪除表字段

語法

  • alter table tablename drop[column] col_name

  • 舉例

alter table emp drop column age;     #刪除age列

修改欄位定義(包括欄位名)

語法

  • alter table tablename change[column] old_col_name column_definition[first | after col_name]

  • 舉例

alter table emp change age agel int(4);  #將age列修改為agel列名int(4)資料型別
  • change 和modify都可以修改表的定義,但是modify修改不了欄位名,change可以,不過change需要寫兩次欄位名(廢話不寫兩個怎麼從舊值改新值)

插入記錄

語法

  • insert into tablename(field1,field2,field3…) values(value1,value2,…)

  • 舉例

insert into emp(ename,hiredate,sal,deptno)values('zzx1','2000-01-01','2000',1);
insert into emp values('lisa','2003-02-01','3000',2,22),('zs','2001-05-06','4000',3,21);   

更新記錄

語法

  • update tablename set field1=value1,field2=value2,…[where condition]

  • 舉例

update emp set sal = 4000 where ename = 'lisa'; #修改記錄ename為lisa的sal為4000

刪除記錄

語法

  • delete from tablename[where condition]

  • 舉例

delete from emp where ename='dony';  #從emp表中刪除ename為dony的記錄

查詢記錄

語法

  • select * from tablename[where condition] order by fieldn [desc|asc] limit offset_start,row_count

  • 處理方式

    1. 排序

      select name,uid from user where id >= 10 and id <= 20 order by uid asc

    2. 分組

      select shell from user group by shell

    3. 過濾查詢結果

      select name,uid from user where id <= 15 having name='zhangsan’

    4. 聚集函式使用

    5. 限制查詢結果顯示的行數

  • 舉例

select * from emp;
select ename,hiredate,sal,deptno from emp;
select * from emp  where ename='lisa' and sal=4000;              #條件查詢
select * from emp order by sal desc;       #根據sal降序排列輸出
select * from emp order by sal asc;        #根據sal增序排列輸出
select * from emp order by sal desc limmit 3;   #根據sal降序排列輸出3行(從0開始)
select * from emp order by sal desc limit 1,3;   #根據sal降序排列輸出1~3行

聚合語法

  • select [field1,field2,…] fun_name from tablename where [where_contition] group by field1,field2… with rollup having [where_contition]

聚合語法舉例

select count(1) from emp;            #統計emp表記錄數賦予新的欄位名
+----------+
| count(1) |
+----------+
|        4 |
+----------+
select deptno,count(1) from emp group by deptno; #根據deptno分類
+--------+----------+
| deptno | count(1) |
+--------+----------+
|      1 |        2 |                     #deptno為1的有2個
|      2 |        1 |
|      3 |        1 |
+--------+----------+
select deptno,count(1) from emp group by deptno with rollup;  #在上面的基礎上統計總人數
+--------+----------+
| deptno | count(1) |
+--------+----------+
|      1 |        2 |
|      2 |        1 |
|      3 |        1 |
|   NULL |        4 |
+--------+----------+
select deptno, count(1) from emp group by deptno having count(1) > 1; #欄位count(1)大於1																	#的值

+--------+----------+
| deptno | count(1) |
+--------+----------+
|      1 |        2 |
+--------+----------+

表連線

  • 內連線 匹配兩張表中互相匹配的記錄

  • 外連線 選出其他不匹配的記錄

    • 左連線 包含所有的左邊表中的記錄甚至是右邊表中沒有和它匹配的記錄
    • 右連線 包含所有的右邊表中的記錄甚至是左邊表中沒有和它匹配的記錄
  • 舉例

select * from emp;
+--------+------------+---------+--------+
| ename  | hiredate   | sal     | deptno |
+--------+------------+---------+--------+
| zzx    | 2000-01-01 | 2000.00 |      1 |
| lisa   | 2003-02-01 | 4000.00 |      2 |
| bjguan | 2004-05-02 | 5000.00 |      1 |
| dony   | 2005-02-05 | 2000.00 |      4 |
+--------+------------+---------+--------+
select * from dept;
+--------+----------+
| deptno | deptname |
+--------+----------+
|      1 | tech     |
|      2 | sale     |
|      3 | hr       |
+--------+----------+
#內連線
select ename,deptname from emp,dept where emp.deptno=dept.deptno;  #內連線查詢兩張表中
+--------+----------+								#deptno相同的記錄的ename deptname
| ename  | deptname |
+--------+----------+
| zzx1   | tech     |
| lisa   | sale     |
| bjguan | tech     |
+--------+----------+

#左連線
select ename,deptname from emp left join dept on emp.deptno=dept.deptno;
+--------+----------+
| ename  | deptname |
+--------+----------+
| zzx    | tech     |
| bjguan | tech     |
| lisa   | sale     |
| dony   | NULL     |
+--------+----------+
#顯示emp中的欄位   如果dept中沒有  就NULL替代
#右連線顯示右邊表    左邊表NULL替代
select ename,deptname from right join dept on emp.deptno=dept.deptno;
+--------+----------+
| ename  | deptname |
+--------+----------+
| zzx    | tech     |
| lisa   | sale     |
| bjguan | tech     |
| NULL   | hr       |
+--------+----------+

索引

  • 建立表時 index(column_name)
create table tea4(
id char(6) not null,
name varchar(6) not null,
age int(3) not null,
gender enum('boy','girl') default 'boy',
index(id),index(name)              #新增普通索引
);

desc tea4;
+--------+--------------------+------+-----+---------+-------+
| Field  | Type               | Null | Key | Default | Extra |
+--------+--------------------+------+-----+---------+-------+
| id     | char(6)            | YES   | MUL | NULL    |       | #kEY為MUL 索引
| name   | varchar(5)         | YES   | MUL | NULL    |       |
| age    | int(3)             | YES   |     | NULL    |       |
| gender | enum('boy','girl') | YES   |     | boy     |       |
+--------+--------------------+------+-----+---------+-------+
  • 表建立後
create index age on tea4(age);                 #為tea4的age欄位建立age索引
Query OK, 0 rows affected (0.01 sec)

desc tea4; #查看錶結構
+--------+--------------------+------+-----+---------+-------+
| Field  | Type               | Null | Key | Default | Extra |
+--------+--------------------+------+-----+---------+-------+
| id     | char(6)            | YES   | MUL | NULL    |       | 
| name   | varchar(5)         | YES   | MUL | NULL    |       |
| age    | int(3)             | YES   | MUL | NULL    |       | #age欄位有索引了
| gender | enum('boy','girl') | YES   |     | boy     |       |
+--------+--------------------+------+-----+---------+-------+


#刪除age索引
drop index age on tea4;   #不需要欄位名了
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

show index from tea4\G;   #列表形式檢視索引
*************************** 1. row ***************************
        Table: tea4
   Non_unique: 1
     Key_name: id
 Seq_in_index: 1
  Column_name: id
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null:
   Index_type: BTREE               #預設索引為B樹    還有B+樹和hash可以設定
      Comment:
Index_comment:
*************************** 2. row ***************************
        Table: tea4
   Non_unique: 1
     Key_name: 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)

主鍵

  • 表建立時
create table tea4 (
id int(4) primary key,                   #單個主鍵   屬性方式新增
name varchar(8)
);

create table tea4(
id int(4),
name varchar(8),
primary key (id)                     #單個主鍵   函式形式
);

create table tea4(
id int(4),
name varchar(8)
primary key(id, name)                    #函式形式 複合主鍵
);
  • 表建立後
alter table tea4 drop primary key;   #刪除tea4主鍵    alter drop 
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

alter table tea4 modify id int(4) primary key;  #給id新增主鍵   change 也行
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

alter table tea4 drop primary key;

alter table tea4 add primary key(id, name);
desc tea4;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| id    | int(4)     | NO   | PRI | NULL    |       | #成功設定主鍵
| name  | varchar(8) | NO   | PRI | NULL    |       | #成功設定主鍵
+-------+------------+------+-----+---------+-------+

欄位的auto_increment屬性 只能一個欄位且是主鍵才能使用,複合主鍵也只能一個欄位使用

外來鍵

  • 語法

    alter table 庫名.表名 add constraint 外來鍵名 foreign key(需加外來鍵的欄位名) references 關聯表名(關聯欄位)

    alter table gz add constraint gz_id_wj foreign key(gz_id) references yg(yg_id) on 操作名 cascade

#建立員工表   主鍵為員工id 自增 資料庫引擎為innodb
create table yg(
yg_id int primary key auto_increment,
name char(16)
)engine=innodb;  #設定資料庫引擎為innodb   還有MyISAM  

在MySQL 5.1之前的版本中,預設的搜尋引擎是MyISAM,從MySQL 5.5之後的版本中,預設的搜尋引擎變更為InnoDB

  • MyISAM

    它是基於傳統的ISAM型別,ISAM是Indexed Sequential Access Method (有索引的 順序訪問方法) 的縮寫,它是儲存記錄和檔案的標準方法.與其他儲存引擎比較,MyISAM具有檢查和修復表格的大多數工具. MyISAM表格可以被壓縮,而且它們支援全文搜尋.它們不是事務安全的,而且也不支援外來鍵。如果事物回滾將造成不完全回滾,不具有原子性。如果執行大量的SELECT,MyISAM是更好的選擇。

    MyISAM儲存引擎的特點是:表級鎖、不支援事務和全文索引,適合一些CMS內容管理系統作為後臺資料庫使用,但是使用大併發、重負荷生產系統上,表鎖結構的特性就顯得力不從心;

  • InnoDB

    這種型別是事務安全的.它與BDB型別具有相同的特性,它們還支援外來鍵.InnoDB表格速度很快.具有比BDB還豐富的特性,因此如果需要一個事務安全的儲存引擎,建議使用它.如果你的資料執行大量的INSERT或UPDATE,出於效能方面的考慮,應該使用InnoDB表,

    對於支援事物的InnoDB型別的表,影響速度的主要原因是AUTOCOMMIT預設設定是開啟的,而且程式沒有顯式呼叫BEGIN開始事務,導致每插入一條都自動Commit,嚴重影響了速度。可以在執行sql前呼叫begin,多條sql形成一個事物(即使autocommit開啟也可以),將大大提高效能。

    InnoDB儲存引擎的特點是:行級鎖、事務安全(ACID相容)、支援外來鍵、不支援FULLTEXT型別的索引(5.6.4以後版本開始支援FULLTEXT型別的索引)。InnoDB儲存引擎提供了具有提交、回滾和崩潰恢復能力的事務安全儲存引擎。InnoDB是為處理巨大量時擁有最大效能而設計的。它的CPU效率可能是任何其他基於磁碟的關係資料庫引擎所不能匹敵的。

  • 注意

    InnoDB表的行鎖也不是絕對的,假如在執行一個SQL語句時MySQL不能確定要掃描的範圍,InnoDB表同樣會鎖全表,例如

    update table set num=1 where name like "a%"
    

    兩種型別最主要的差別就是InnoDB支援事務處理與外來鍵和行級鎖。而MyISAM不支援。所以MyISAM往往就容易被人認為只適合在小專案中使用。

#建立工資表
create table gz(
gz_id int,
name char(16),
gz float(7,2),
foreign key(gz_id) references yg(yg_id)    #建立外來鍵
on update cascade on delete cascade        #同步更新update、同步刪除delete
)engine=innodb;


#插入員工資料
insert into yg(name) values('Jerry'),('Tom');
insert into gz(gz_id,name,gz) values(1,'Jerry',12000),(2,'Tom',8000);

select * from gz;
+-------+-------+----------+
| gz_id | name  | gz       |
+-------+-------+----------+
|     1 | Jerry | 12000.00 |
|     2 | Tom   |  8000.00 |
+-------+-------+----------+

#修改員工表中的id  檢視同步更新功能
update yg set yg_id=1234 where name=Jerry;
select * from gz;
+-------+-------+----------+
| gz_id | name  | gz       |
+-------+-------+----------+
|  1234 | Jerry | 12000.00 |  #工資表中的id也被修改了
|     2 | Tom   |  8000.00 |
+-------+-------+----------+

#刪除Jerry   檢視同步刪除功能
delete from yg where name='Jerry';
select * from gz;
+-------+------+---------+
| gz_id | name | gz      |
+-------+------+---------+
|     2 | Tom  | 8000.00 |        #工資表中Jerry行也沒了
+-------+------+---------+


#這裡因為工資表沒有設定主鍵 所以有幾個問題
insert into gz(gz_id,name,gz) values(2,'Jorry',10000.0);
insert into gz(gz_id,name,gz) values(2,'Jorry',10000.0);
insert into gz(gz_id,name,gz) values(null,'Jorry',5000.0);

select * from gz;
+-------+-------+----------+
| gz_id | name  | gz       |
+-------+-------+----------+
|     2 | Tom   |  8000.00 |
|     2 | Jorry | 10000.00 |
|     2 | Jorry | 10000.00 |
|  NULL | Jorry | 10000.00 |   #多條重複記錄    還有空值  不合理
+-------+-------+----------+

#設定主鍵
delete from gz where name='Jorry'; #先刪除不合規的記錄
Query OK, 3 rows affected (0.00 sec)

alter table gz modify gz_id int not null primary key;   #非空 主鍵
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0

insert into gz(gz_id,name,gz) values(null,'Jorry',5000);
ERROR 1048 (23000): Column 'gz_id' cannot be null   #空值無法插入
insert into gz(gz_id,name,gz) values(2,'Jorry',1090);
ERROR 1062 (23000): Duplicate entry '2' for key 'PRIMARY'   #主鍵不能重複



#刪除外來鍵
show create table gz\G;  #檢視工資表的外來鍵名字
       Table: gz
Create Table: CREATE TABLE `gz` (
  `gz_id` int(11) NOT NULL,
  `name` char(16) DEFAULT NULL,
  `gz` float(7,2) DEFAULT NULL,
  PRIMARY KEY (`gz_id`),
  CONSTRAINT `gz_ibfk_1` FOREIGN KEY (`gz_id`) REFERENCES `yg` (`yg_id`) ON DELETE CASCADE ON UPDATE CASCADE         #外來鍵名為'gz_ibfk_1'
) ENGINE=InnoDB DEFAULT CHARSET=latin1


alter table gz drop foreign key 'gz_ibfk_1';  #刪除外來鍵


檔案匯入匯出

secure_file_priv引數

  • 預設為NULL ,表示mysqld不允許匯入匯出
  • secure_file_priv的值為/tmp/時,表示只允許在/tmp/目錄下匯入匯出
  • secure_file_priv的值沒有具體值時,表示不限制mysqld的匯入匯出

匯入匯出命令語法

  • 匯入

    load data infile ‘檔案路徑’ into table 表名 fields terminated by ‘欄位分隔符’ lines terminated by ‘記錄分隔符’;

  • 匯出

    select * from 表名 into outfile ‘匯出檔案路徑’ fields terminated by ‘欄位分隔符’ lines terminated by '記錄分隔符’

mkdir /myload
chown mysql /myload  #修改檔案所有者   防止許可權問題
vim /etc/my.cnf
=========================
[mysqld]
secure_file_priv='/myload'
==============================
systemctl restart mysqld

mysql -uroot -p
show variables like 'secure_file_priv';
+------------------+----------+
| Variable_name    | Value    |
+------------------+----------+
| secure_file_priv | /myload/ |    #有了
+------------------+----------+

#拿/etc/password做測試
cp /etc/passwd /myload  #將要匯入的檔案放入允許匯入匯出的/myload/目錄下
mysql -uroot -p
create database db3;
create table db3.user(  #符合/etc/passwd的內容  七列
	name char(50),
	password char(1),
	uid int,
	gid int,
	comment char(150),
	homedir char(50),
	shell char(50)
	);

#匯入命令
load data infile '/myload/passwd' into table db3.user fields terminated by ':' lines terminated by '\n';
#匯入檔案為/myload/passwd 欄位分隔為:  記錄分隔為換行符



#匯出命令
select * from db3.user into outfile '/myload/user1.txt' fields terminated by '||' lines terminated by '\n';