1. 程式人生 > >資料庫 DB MySQL 基本操作 CRUD 多表 MD

資料庫 DB MySQL 基本操作 CRUD 多表 MD

目錄

Markdown版本筆記 我的GitHub首頁 我的部落格 我的微信 我的郵箱
MyAndroidBlogs baiqiantao baiqiantao bqt20094 [email protected]

資料庫 DB MySQL 基本操作 CRUD 多表 MD
***
目錄
===

操作資料庫

建立資料庫:create

  • 建立一個名稱為mydb1的資料庫 create database mydb1;
  • 建立一個使用gbk字符集的mydb2資料庫 create database mydb2 character set gbk;
  • 建立一個使用utf8字符集,並帶校對規則
    的mydb3資料庫 create database mydb3 character set utf-8 collate utf8_bin;

檢視資料庫:show

  • 檢視當前資料庫伺服器中的所有資料庫 show databases;
  • 檢視前面建立的mydb2資料庫的定義資訊 show create database mydb3;

修改資料庫:alter

  • 把mydb2資料庫的字符集修改為utf8 alter database mydb2 character set utf8;

刪除資料庫:drop

  • 刪除前面建立的mydb1資料庫 drop database mydb1;

選擇資料庫:use

  • 進入資料庫,切換資料庫 use mydb1;
  • 檢視當前所選的資料庫 select database();

操作表

MySQL常用資料型別

  • 字串型:VARCHARCHAR
  • 大資料型別:BLOBTEXT
  • 整數數值型:TINYINTSMALLINTINTBIGINT
  • 浮點數值型:FLOATDOUBLE
  • 邏輯型:BIT
  • 日期型:DATETIMEDATETIMETIMESTAMP(時間戳)

定義單表字段的約束

  • 定義主鍵約束:primary key 不允許為空,不允許重複
  • 刪除主鍵:alter table tablename drop primary key
  • 主鍵自動增長:auto_increment
  • 定義唯一約束:unique
  • 定義非空約束:not null
  • 定義外來鍵約束:foreign key

建立表

注意:建立表前,要先使用 use db_name 語句使用庫。

案例:建立一個員工表 employee

create table employee(
   id int primary key auto_increment,
   name varchar(20) unique,
   gender bit not null,
   birthday date,
   entry_date date,
   job varchar(40),
   salary double,
   resume text
);

查看錶

  • 查看錶結構:desc tabName
  • 檢視當前資料庫中所有表:show tables
  • 檢視當前資料庫表建表語句:show create table tabName

修改表

  • 在上面員工表的基本上增加一個image列:alter table employee add image blob;
  • 修改job列,使其長度為60:alter table employee modify job varchar(60);
  • 刪除gender列:alter table employee drop gender;
  • 表名改為user:rename table employee to user;
  • 修改表的字符集為gbk:alter table user character set gbk;
  • 列名name修改為username:alter table user change name username varchar(20);

刪除表
刪除user表:drop table user;

操作表記錄

INSERT

INSERT INTO table [(column [, column...])] VALUES (value [, value...]);
  • 插入的資料應與欄位的資料型別相同。
  • 資料的大小應在列的規定範圍內,例如:不能將一個長度為80的字串加入到長度為40的列中。
  • 在values中列出的資料位置必須與被加入的列的排列位置相對應。
  • 字元和日期型資料應包含在單引號中。
  • 插入空值:不指定或insert into table value(null)
  • 如果要插入所有欄位可以省寫列列表,直接按表中欄位順序寫值列表

向表中插入四個員工的資訊:

insert into employee (id,name,gender,birthday,entry_date,job,salary,resume) values (null,'張飛',1,'1999-09-09','1999-10-01','打手',998.0,'老三');
insert into employee values (null,'關羽',1,'1998-08-08','1998-10-01','財神爺',9999999.00,'老二');
insert into employee values (null,'劉備',0,'1990-01-01','1991-01-01','ceo',100000.0,'老大'),(null,'趙雲',1,'2000-01-01','2001-01-01','保鏢',1000.0,'七進七出');

UPDATE

UPDATE  tbl_name SET col_name1=expr1 [, col_name2=expr2 ...] [WHERE where_definition]  
  • UPDATE語法可以用新值更新原有錶行中的各列。
  • SET子句指示要修改哪些列和要給予哪些值。
  • WHERE子句指定應更新哪些行。如沒有WHERE子句,則更新所有的行

案例

  • 將所有員工薪水修改為5000元:update employee set salary = 5000;
  • 將姓名為’張飛’的員工薪水修改為3000元:update employee set salary = 3000 where name='張飛';
  • 將姓名為’關羽’的員工薪水修改為4000元,job改為ccc:update employee set salary=4000,job='ccc' where name='關羽';
  • 將劉備的薪水在原有基礎上增加1000元:update employee set salary=salary+1000 where name='劉備';

DELETE

delete from tbl_name [WHERE where_definition]  

如果不使用where子句,將刪除表中所有資料
Delete語句不能刪除某一列的值(可使用update)
使用delete語句僅刪除記錄,不刪除表本身。如要刪除表,使用drop table語句
同insert和update一樣,從一個表中刪除記錄將引起其它表的參照完整性問題,在修改資料庫資料時,頭腦中應該始終不要忘記這個潛在的問題
刪除表中資料也可使用TRUNCATE TABLE語句,它和delete有所不同,參看mysql文件。

案例

  • 刪除表中名稱為’張飛’的記錄:delete from employee where name='張飛';
  • 刪除表中所有記錄:delete from employee;
  • 使用truncate刪除表中記錄:truncate table employee;

SELECT

基本查詢

  • 查詢表中所有學生的資訊:select * from exam;
  • 查詢表中所有學生的姓名和對應的英語成績:select name,english from exam;
  • 過濾表中重複資料:select distinct english from exam;
  • 在所有學生分數上加10分特長分顯示:select name, math+10, english+10, chinese+10 from exam;
  • 統計每個學生的總分:select name, english+math+chinese from exam;
  • 使用別名表示學生總分(as可以省略):select name as 姓名 ,english+math+chinese 總成績 from exam;

對查詢結果進行過濾 where

  • 查詢姓名為張飛的學生成績:select * from exam where name='張飛';
  • 查詢英語成績大於90分的同學:select * from exam where english > 90;
  • 查詢總分大於230分的所有同學:select name 姓名, math+english+chinese 總分 from exam where math+english+chinese>230;
  • 查詢英語分數在 80-100之間的同學:select * from exam where english between 80 and 100;
  • 查詢數學分數為75,76,77的同學,in(集合):select * from exam where math in(75,76,77);
  • 查詢所有姓張的學生成績,%代表任意個字元,_代表一個字元:select * from exam where name like '張%';
  • 查詢數學分>70且語文分>80的同學,支援and,or,not邏輯運算子:select * from exam where math>70 and chinese>80;

對查詢結果進行排序 order by
asc 升序(預設),desc 降序;order by 語句應放在結尾

  • 對語文成績排序後輸出:select name,chinese from exam order by chinese desc;
  • 對總分排序按從高到低的順序輸出:select name 姓名,chinese+math+english 總成績 from exam order by 總成績 desc;
  • 對姓張的學生成績排序輸出:select name 姓名,chinese+math+english 總成績 from exam where name like '張%' order by 總成績 desc;

聚合函式 Count、SUM、AVG、MAX、MIN
Count:用來統計符合條件的行的個數

  • 統計一個班級共有多少學生:select count(*) from exam;
  • 統計數學成績大於90的學生有多少個:select count(*) from exam where math>70;
  • 統計總分大於230的人數有多少:select count(*) from exam where math+english+chinese > 230;

SUM:用來將符合條件的記錄的指定列進行求和操作,注意:sum僅對數值起作用,否則會報錯

  • 統計一個班級數學總成績:select sum(math) from exam;
  • 統計一個班級語文、英語、數學各科的總成績:select sum(math),sum(english),sum(chinese) from exam;
  • 注意:在執行計算時,只要有null參與計算,整個計算的結構都是null,此時可以用ifnull函式進行處理
  • 統計一個班級語文、英語、數學的成績總和:select sum(ifnull(chinese,0)+ifnull(english,0)+ifnull(math,0)) from exam;
  • 統計一個班級語文成績平均分:select sum(chinese)/count(*) 語文平均分 from exam;

AVG:用來計算符合條件的記錄的指定列的值的平均值

  • 求一個班級數學平均分:select avg(math) from exam;
  • 求一個班級總分平均分:select avg(ifnull(chinese,0)+ifnull(english,0)+ifnull(math,0)) from exam;

MAX/MIN:用來獲取符合條件的所有記錄指定列的最大值和最小值

  • 求班級最高分:select max(ifnull(chinese,0)+ifnull(english,0)+ifnull(math,0)) from exam;

分組查詢 group by

  • 對訂單表中商品歸類後,顯示每一類商品的總價:select product,sum(price) from orders group by product;
  • 查詢購買了幾類商品,並且每類總價大於100的商品:select product 商品名,sum(price)商品總價 from orders group by product having sum(price)>100;
  • 查詢單價小於100而總價大於150的商品的名稱:select product from orders where price<100 group by product having sum(price)>150;

其他知識點

where子句和having子句的區別

  • where子句在分組之前進行過濾,having子句在分組之後進行過濾
  • having子句中可以使用聚合函式,where子句中不能使用聚合函式
  • where子句不能在對資料進行某些運算後使用,having子句可以
  • 很多情況下使用where子句的地方可以使用having子句進行替代

順序
sql語句書寫順序:select from where groupby having orderby
sql語句執行順序:from where select group by having order by

備份資料庫
備份前先退出資料庫,回到CMD視窗下,命令:quit
在cmd視窗下執行命令:

mysqldump -u root(使用者名稱) -p dbName(資料庫名) > c:/1.sql(可不帶字尾名,結尾不能帶分號)

例如:

quit
mysqldump -u root -p dbName > c:/1.sql

恢復資料庫
要注意恢復資料只能恢復資料本身,原先的資料庫(名)沒法恢復,所以恢復前需要先自己創建出資料檔案
恢復方式1:在cmd視窗下

mysql -u root -p dbName < c:/1.sql

例如

mysql -u root -p dbName
create database newDBName;

恢復方式2:在mysql命令下

source c:/1.sql

例如

use newDBName;
source c:/newDBName.sql

多表設計與多表查詢

外來鍵約束

表是用來儲存現實生活中的資料的,而現實生活中資料和資料之間往往具有一定的關係,我們在使用表來儲存資料時,可以明確的宣告表和表之前的依賴關係,命令資料庫來幫我們維護這種關係,像這種約束就叫做外來鍵約束

定義外來鍵約束:

foreign key(本表的列名 ordersid) references orders(id)(引用的表明及列名)

案例:

create table dept(
   id int primary key auto_increment,
   name varchar(20)
);
create table emp(
   id int primary key auto_increment,
   name varchar(20),
   dept_id int,
   foreign key(dept_id) references dept(id)
);

多表設計

  • 一對多:在多的一方儲存一的一方的主鍵做為外來鍵
  • 一對一:在任意一方儲存另一方的主鍵作為外來鍵
  • 多對多:建立第三方關係表儲存兩張表的主鍵作為外來鍵,儲存他們對應關係

多表查詢

笛卡爾積查詢
將兩張表的記錄進行一個相乘的操作查詢出來的結果就是笛卡爾積查詢
如果左表有n條記錄,右表有m條記錄,笛卡爾積查詢出有n*m條記錄,其中往往包含了很多錯誤的資料,所以這種查詢方式並不常用

select * from dept,emp;

內連線查詢
查詢的是左邊表和右邊表都能找到對應記錄的記錄

select * from dept,emp where dept.id = emp.dept_id;
select * from dept inner join emp on dept.id=emp.dept_id;

外連線查詢
左外連線查詢:在內連線的基礎上增加左邊表有而右邊表沒有的記錄

select * from dept left join emp on dept.id=emp.dept_id;

右外連線查詢:在內連線的基礎上增加右邊表有而左邊表沒有的記錄

select * from dept right join emp on dept.id=emp.dept_id;

全外連線查詢:在內連線的基礎上增加左邊表有而右邊表沒有的記錄和右邊表有而左表表沒有的記錄

select * from dept full join emp on dept.id=emp.dept_id;

但是mysql不支援全外連線,不過我們可以使用union關鍵字模擬全外連線

select * from dept left join emp on dept.id = emp.dept_id
union
select * from dept right join emp on dept.id = emp.dept_id;

多表查詢例項

建立表a

create table a(id int primary key,job varchar(20));
insert into a values(1,'AA'), (2,'BB'), (3,'CC');
select * from a;

建立表b

create table b(id int ,name varchar(20) ,foreign key(id) references a(id));
insert into b values(1,'bqt'), (2,'bqt2'), (2,'bqt3');
select * from b;

PS:
被參照的a(id)必須定義為unique才可以被參照,否則報錯(邏輯錯誤)。
插入資料的id必須在被參照的表中已經存在,否則報錯(邏輯錯誤)。

1、笛卡爾積查詢

select * from a,b;

2、內連線查詢:查詢的是左邊表和右邊表都能找到對應記錄的記錄

select * from a,b where a.id = b.id;
或
select * from a inner join b on a.id=b.id;

3、左外連線查詢:在內連線的基礎上增加左邊表有而右邊表沒有的記錄

select * from a left join b on a.id=b.id;

4、右外連線查詢:在內連線的基礎上增加右邊表有而左邊表沒有的記錄

select * from a right join b on a.id=b.id;

PS:由於右邊表參照左邊表,所以不存在右邊表有而左邊表沒有的記錄。

5、全外連線查詢:在內連線的基礎上增加左邊表有而右邊表沒有,和右邊表有而左表表沒有的記錄

select * from a left  join b on a.id = b.id
union
select * from a right join b on a.id = b.id;

補充

Java 獲取所有表

public List<String> getChatTables(){
    initDataBaseHelper();

    ArrayList<String> tables = new ArrayList<>();
    Cursor cursor = dbWrite.rawQuery("select name from sqlite_master where type='table' and name like 'chat%' ", null);
    cursor.moveToPrevious();

    while(cursor.moveToNext()){
       String name = cursor.getString(0); //遍歷出表名
       if(name.startsWith("chat_")){ //這一步的判斷是可以省略的
           tables.add(name);
       }
    }
      cursor.close();
      return tables;
}

檢視 Android 資料庫表結構方法

在android中,為某個應用程式建立的資料庫檔案位於Android裝置的 /data/data/包名/databases 資料夾中,並且只有此應用程式自己可以訪問,其它應用程式是不能訪問的。開發者若要檢視資料庫中的內容,方式有兩種 :

  • 1、將資料庫檔案通過File Explorer或其他方式匯出後使用視覺化工具SQLite Expert軟體開啟(工具是收費的)
  • 2、在cmd命令下通過使用系統自帶的sqlite3命令檢視。

下面介紹第二種方式,大致步驟為:

  • 1、可以先通過adb devices檢視是否有裝置連線
  • 2、通過adb shell進入手機根目錄,若測試的是真機,預設為普通使用者許可權,此時會有一個符號 $(超管為 #),此時沒有訪問/data目錄的許可權,若手機已獲得了root許可權(基本上沒有手機會主動給這個許可權),可以輸入susu root申請root許可權,然後在手機上點選授權(如有必要),這樣就可以訪問/data目錄了
  • 3、定位到指定目錄cd data/data/包名/databases,檢視目錄下的檔案ls -l,注意*.db-journal為臨時檔案
  • 4、使用sqlite3命令開啟資料庫檔案sqlite3 person.db,若提示sh: sqlite3: not found,解決辦法見下文
  • 5、執行資料庫語句select * from person;,注意最後要有一個分號;也可執行其它指令,如.table檢視所有表,.schema檢視所有語句,.help檢視幫助
  • 6、若顯示中文時亂碼,詳見下文

命令列顯示中文亂碼解決方案

1、退出後重新開啟CMD視窗,輸入:chcp 65001 回車
注意 65001 是指使用UTF-8的編碼,GB2312 為 936,可以從 EditPlus 工具的選單--文件--文件型別 檢視
2、在命令列標題欄上點選右鍵,選擇屬性 - 字型,將字型修改為Lucida Console(預設為點陣字型),確定
3、完成後再通過命令進入sqlite3,select一下含有中文的記錄,亂碼就解決了。

sqlite3:not found 解決方法

sqlite3 為一個可執行指令碼程式,在system/xbin/下面,某些品牌手機 rom 不帶這個東西,導致使用該工具出現 sqlite3:not found 錯誤,下面就詳細講解如何解決此問題。

注意:

  • sqlite3 一般情況下都是通用的,所以隨便去找個 sqlite3 就好,比如 這個這個
  • 若此檔案還是不行,那就使用相應版本的模擬器中的/system/xbin目錄下的 sqlite3
  • 不能使用 x86 模擬器上的 sqlite3,否則執行會出現 /system/xbin/sqlite3: not executable: magic 7F45錯誤
  • 若也缺少 libncurses.so 檔案,會報 libncurses.so not found錯誤,處理方式是一樣的,建議同時匯入這兩個檔案

完整步驟:
1、檢視是否連線裝置:adb devices

2、獲取root許可權

adb shell
su

3、讓/system資料夾可讀寫

mount -o remount,rw -t yaffs2 /dev/block/mtdblock3 /system

4、匯入所需的檔案到sdcard
從模擬器的 /system/xbin 中匯出 sqlite3 檔案,從 /system/lib 中匯出 libncurses.so 檔案
將上面匯出的檔案或從網上下載的檔案匯入到真機的sdcard中
為驗證是否匯入成功,可先ls,我們發現裡面有一個sdcard,我們進入此目錄cd sdcard,再ls,若發現裡面有我們匯入的這兩個檔案,證明匯入成功

5、將sdcard中的檔案複製到手機系統相應目錄中
首先切換到根目錄,然後執行以下命令:

cd /
cat /sdcard/sqlite3 > /system/xbin/sqlite3
cat /sdcard/libncurses.so > /system/lib/libncurses.so

6、修改檔案許可權

chmod 4755 /system/xbin/sqlite3
chmod 4755 /system/lib/libncurses.so

7、設定 /system為只讀檔案

mount -o remount,ro -t yaffs2 /dev/block/mtdblock3 /system

至此,就可以使用 sqlite3 命令來操作 SQLite 資料庫了。

2018-4-16