mysql語法與問題

mysql表操作

  1. 模糊查旬
    like
    between and
    in
    is null | is not null
    like

案例: 查詢員工名中包含了"a"字符的所有員工的信息

select * from employees where last_name like '%a%'; // %:通配符,表示任意多個(gè)字符,也可表示0個(gè)字符, _:任意一個(gè)字符;

案例: 查詢第三個(gè)字符為n或第五個(gè)字符為l的員工信息
select * from employees where last_name like '__n_l%';

案例: 查詢員工信息表中員工名第二個(gè)字符是"_"的員工信息

select * form employees where last_name like '_\_%'; //支持java的轉(zhuǎn)義字符
select * from employees where last_name like '_&_' escape '&'; // escape '&':說明&這個(gè)符號(hào)是轉(zhuǎn)義字符,mysql推薦這樣寫;

注意:一般情況下,like都是通配符連在一起使用的.
between and
案例:查詢員工工資中10000到20000之間到員工信息

select * from employees where salary>=10000 and salary<=20000;
select * from employees where salary between 10000 and 20000;

in:
案例:查詢員工的工種編號(hào)是 it_prog,ad_vp,ad_pres中任意一個(gè)的員工信息

select * from employee where job_id='it_prog' or job_id='ad_vp' or job_id='ad_pres';
select * from employees where job_id in('it_prog','ad_vp','ad_pres')

in:判斷某個(gè)字段的值是否屬于in列表中的某一項(xiàng)
1.使用in比使用or后sql語句更簡(jiǎn)單
2.in的值必須是同一種數(shù)據(jù)類型或者兼容
is null | is no null:
案例:查詢沒有獎(jiǎng)金率的員工信息

select * from employees commission_pct is null; 注意:commission_pct=null這個(gè)寫法不能判斷null值
查詢獎(jiǎng)金率的就取反:
select * from employees commission_pct is not null; 注意:當(dāng)然這里is not也不能換成<>不等號(hào).
補(bǔ)充一個(gè)東西:
安全等于號(hào):<=> , 這個(gè)符號(hào)可以判斷null值,也可以判斷普通數(shù)值;
is null:只能判斷null值,不能判斷普通數(shù)值
=:只能判斷普通數(shù)值,不能判斷null值

事務(wù)機(jī)制

TCL:Transaction Control Language,事務(wù)控制語言
事務(wù):在MySQL數(shù)據(jù)庫中表示一條或多條Sql語句組合在一起的一個(gè)執(zhí)行單元.這個(gè)執(zhí)行單元要么全部執(zhí)行,要么全部不執(zhí)行,否則就會(huì)出現(xiàn)邏輯錯(cuò)誤!
比如銀行里的轉(zhuǎn)賬這個(gè)事情:

A賬號(hào)余額:1000

B賬號(hào)余額:1000

現(xiàn)在A轉(zhuǎn)500元給B,那么要完成這個(gè)轉(zhuǎn)賬的事務(wù),數(shù)據(jù)中的SQL應(yīng)該是這樣的執(zhí)行過程:

①A賬號(hào)上要減少500元

update 儲(chǔ)蓄表 set A.余額=A.余額-500 where 賬號(hào)名='A';

②B賬號(hào)上要增加500元

update 儲(chǔ)蓄表 set B.余額=B.余額+500 where 賬號(hào)名='B';

如果沒有事務(wù)處理這個(gè)功能,上面的情況下,很可能會(huì)發(fā)生這樣的情況:

①執(zhí)行成功 A的余額變?yōu)?500

剛開始執(zhí)行②的時(shí)候,突然出現(xiàn)某系統(tǒng)系統(tǒng)錯(cuò)誤,導(dǎo)致②執(zhí)行失敗!

①√②×:A的錢減少了,B的錢沒增加!

所以在類似的場(chǎng)景需求中我們需要事務(wù)處理:實(shí)現(xiàn)將①和②的SQL語句綁定在一起,要么都執(zhí)行成功,沒的事! 要么不管是①執(zhí)行出錯(cuò)還是②執(zhí)行出錯(cuò),數(shù)據(jù)庫里的數(shù)據(jù)狀態(tài)會(huì)回滾到?jīng)]有執(zhí)行任何①或②里的SQL語句之前!
①什么是存儲(chǔ)引擎:
在mysql中的數(shù)據(jù)是用各種不同的技術(shù)來存儲(chǔ)在磁盤文件(或內(nèi)存)當(dāng)中的,這種具體的存儲(chǔ)技術(shù)就是我們說的存儲(chǔ)引擎.
②我們可以通過show engines;命令來查看mysql支持的存儲(chǔ)引擎.
③在mysql可以選擇的這些存儲(chǔ)引擎中,
innodb,myisam,memory這個(gè)三個(gè)是最常用的,但是其中只有innodb支持事務(wù)處理,而其他是不支持事務(wù)處理的.
事務(wù)的ACID特點(diǎn):
①原子性(Atomicity):組成事務(wù)的SQL語句不可在分,要么都執(zhí)行,要么都不執(zhí)行.
②一致性(Consistency):事務(wù)必須讓數(shù)據(jù)的數(shù)據(jù)狀態(tài)變化到另一個(gè)一致性的狀態(tài),比如:剛剛的例子中A和B的余額總和是2000,轉(zhuǎn)賬后,A和B的余額總和不能變.前后具有一致性.
③隔離性(Isolation):一個(gè)事務(wù)的執(zhí)行,不受其他事務(wù)的干擾,相互應(yīng)該是隔離的,但是實(shí)際上是很難做到的,要通過隔離級(jí)別做選擇!
④持久性(Durability):一個(gè)事務(wù)被提交,并成功執(zhí)行,那么它對(duì)數(shù)據(jù)的修改就是永久性的.接下來的其他操作或出現(xiàn)的故障,不能影響到它執(zhí)行的結(jié)果!

MySQL的事務(wù)的創(chuàng)建:

①隱視事務(wù):
事務(wù)沒有明顯的開始和結(jié)束的標(biāo)記.這時(shí)候像insert語句,update語句和delete語句,每一條SQL語句就默認(rèn)是一個(gè)事務(wù).顯然,隱視事務(wù)在類似轉(zhuǎn)賬的邏輯業(yè)務(wù)需求的時(shí)候,就無法處理了!
②顯示事務(wù):
說白了,這個(gè)事務(wù)模式,就要我們中程序中手動(dòng)的用命令來開啟事務(wù),和結(jié)束事務(wù),并讓事務(wù)里的多條SQL語句去執(zhí)行.
注意:默認(rèn)MySQL是開啟自動(dòng)提交事務(wù)的,用show variables like 'autocommit';命令可以查看到. 所以開啟顯示事務(wù)前,要關(guān)掉它,用set autocommit=0;只對(duì)本身會(huì)話有效,如重新登陸mysql就是打開了自動(dòng)提交.
例子:銀行轉(zhuǎn)賬:
開啟事務(wù):執(zhí)行語句:結(jié)束事務(wù)
set autocommit=0;
start transaction;
編寫事務(wù)中的SQL語句(主要是:select update delete insert等語句)
語句1;語句2;........
commit; #提交事務(wù)去真正執(zhí)行(結(jié)束了)
ROLLBACK; #回滾事務(wù),恢復(fù)數(shù)據(jù)庫執(zhí)行前的狀態(tài)!(回到執(zhí)行前,也是一個(gè)事務(wù)結(jié)束了。)
1.建表,插入兩條數(shù)據(jù),A,B都有1000元:

DROP TABLE IF EXISTS account;
   CREATE TABLE account(
     id INT PRIMARY KEY AUTO_INCREMENT,
     username VARCHAR(20),
    balance DOUBLE
);
INSERT INTO account(username,balance) VALUES('A',1000),('B',1000);

2.事務(wù),A向B轉(zhuǎn)賬500,兩條記錄同時(shí)更改,但要同步。

SET autocommit = 0;
START TRANSACTION;  #開啟事務(wù)
UPDATE account SET balance=balance-500 WHERE username='A';
UPDATE account SET balance=balance+500 WHERE username='B';
commit;   #提交事務(wù)

-----當(dāng)有多個(gè)事務(wù)同時(shí)訪問數(shù)據(jù)庫中的同一個(gè)數(shù)據(jù)時(shí),如果沒有采取必要的隔離機(jī)制,就會(huì)導(dǎo)致各種并發(fā)錯(cuò)誤發(fā)生,不是數(shù)據(jù)丟失:
兩個(gè)事務(wù)t1,t2:

①臟讀: 當(dāng)t2正在更新某個(gè)字段但還沒有提交數(shù)據(jù)庫執(zhí)行時(shí),t1在這個(gè)時(shí)刻正好讀取這個(gè)字段的數(shù)據(jù),然后t2(java中)在發(fā)生錯(cuò)誤,然后回滾數(shù)據(jù),導(dǎo)致t1讀取到數(shù)據(jù)就是t2更新時(shí)的臨時(shí)數(shù)據(jù),而且最終沒有更新成功的無效數(shù)據(jù)!

②不可重復(fù)讀:t1讀取一個(gè)字段是數(shù)值,然后t2更新了這個(gè)字段,之后t1在讀取同一個(gè)字段,值發(fā)生了變化!因?yàn)楹芏虝r(shí)間內(nèi)t1只想讀取初始值,但由于t2的原因,導(dǎo)致一不致性。

③幻讀:t1讀取一個(gè)字段是數(shù)值,然后t2對(duì)這個(gè)字段插入新數(shù)值,t1在讀突然就多了幾行數(shù)據(jù).
數(shù)據(jù)庫事務(wù)的隔離性:
數(shù)據(jù)庫必須具有隔離這種并發(fā)運(yùn)行的事務(wù)的能力,避免這些個(gè)錯(cuò)誤現(xiàn)象!

一個(gè)事務(wù)與其他事務(wù)隔離的程度稱為隔離級(jí)別:數(shù)據(jù)庫規(guī)定了事務(wù)隔離級(jí)別,不同隔離級(jí)別對(duì)應(yīng)不同的干擾程度,級(jí)別越高,數(shù)據(jù)一致性越好,但并發(fā)性越弱!MySQL數(shù)據(jù)庫支持四個(gè)不同隔離級(jí)別,這四個(gè)由底到高的級(jí)別是:
read uncommitted; 讀未提交數(shù)據(jù)
read commited; 讀已提交數(shù)據(jù)
repeatable read; 可重復(fù)讀(默認(rèn))
serialable; 串行化
演示隔離級(jí)別:
(在cmd命令窗口演示,要模擬并發(fā)情況,需要不同客戶端,linux中直接可以打開多個(gè)窗口)
1.停目,重新啟動(dòng)mysql服務(wù)。

       Windos:
       >net stop mysql
       >net start mysql
      Linux:
      #systemctl stop/start mysqld

2.查看當(dāng)前隔離級(jí)別:默認(rèn):repeatable read;
登陸mysql后:
select @@tx_isolation; #mysql8.x已棄用
select @@transaction_isolation;
3.設(shè)置隔離級(jí)別:有會(huì)話,全局級(jí)別。
全局級(jí)的:設(shè)置全局的事務(wù)隔離級(jí)別,該設(shè)置不會(huì)影響當(dāng)前已經(jīng)連接的會(huì)話,設(shè)置完畢后,新打開的會(huì)話,將使用新設(shè)置的事務(wù)隔離級(jí)別。
會(huì)話級(jí)的:設(shè)置本次會(huì)話的事務(wù)隔離級(jí)別,只在本會(huì)話有效,不會(huì)影響到其它會(huì)話。
本例t1,t2:會(huì)話級(jí)的測(cè)試,不同會(huì)話之間不影響彼此。
首先t1事務(wù):打開一個(gè)命令窗口,登入mysql服務(wù)。
select @@transaction_isolation; #查看隔離級(jí)別
set session transaction isolation level read uncommitted; #設(shè)置最低級(jí)別的,讀未提交的數(shù)據(jù),出臟讀現(xiàn)象。
set autocommit =0; #因?yàn)槊看瓮顺鰉ysql后,session重新建立,又是默認(rèn)打開了提交事務(wù),所以要關(guān)
START TRANSACTION;
use test;
update account set username='C' where id=1; #修改表第一條記錄username='C;
注意:此處不寫提交語句(commit;),命令窗口不關(guān)閉
查看一下表,可以看到表數(shù)據(jù)修改了。馬上進(jìn)入t2打開另一個(gè)命令窗口,進(jìn)入mysql
其次t2:
use test;
select *from account;
可以發(fā)現(xiàn)該表的數(shù)據(jù)沒有修改,仍是'A',出現(xiàn)了臟讀。
設(shè)置與t1同一隔離級(jí)別:
set session transaction isolation level read uncommitted;
再查詢:
select *from account; #數(shù)據(jù)修改了
再次t1回滾:
rollback;
又到t2中
select *from account;

其它級(jí)別自行測(cè)試:
第二級(jí)別: 臟讀沒有了,但不可重復(fù)讀和幻讀仍然有!

第三級(jí)別:沒有臟讀,沒有不可重復(fù)讀,仍然有幻讀!

第四個(gè)級(jí)別:可以解決所有問題! 會(huì)使性能十分低下!

事務(wù)回滾點(diǎn)。
主要是關(guān)鍵字:savepoint
SET autocommit = 0;#開啟事務(wù)
START TRANSACTION;
編寫sql語句

DELETE FROM account WHERE id=1;
SAVEPOINT a; #設(shè)置保存點(diǎn)
DELETE FROM account WHERE id=2;

結(jié)束事務(wù)

ROLLBACK TO a; #回滾到保存點(diǎn)

java開啟事務(wù),提交事務(wù),回滾事務(wù)。

上面是mysql中的硬編碼測(cè)試,這里我們用到j(luò)ava代碼開啟事務(wù)。
首先有一個(gè)數(shù)據(jù)庫連接: conn
其次:conn.setAutoCommit(false);相當(dāng)于:

mysql>set autocommit =0;
   mysql>start transcation ;

再次,提交,回滾結(jié)束事務(wù):當(dāng)然了要寫異常處理。
conn.commit();
conn.rollback();
例 junit 測(cè)試:

 /*
     * 支持事務(wù)的查詢測(cè)試。
     */
    @Test
    void testGetIntTranscation() throws SQLException {
        Connection conn = JdbcUtils.getConnection();
        User user = null;
        conn.setAutoCommit(false);  //開啟事務(wù)
        try {
            user = userDao.get(conn, 5);  //可以有很多語句,這里只一條
            conn.commit();//提交事務(wù)
        } catch (Exception e) {
            e.printStackTrace();
            try {
                conn.rollback();  //有異常,回滾
            }catch(SQLException e1) {
                e1.printStackTrace();
            }
        } finally {
            JdbcUtils.closeConn(conn);
        }
        System.out.println(user);
    }

問題

  1. java.sql.SQLNonTransientConnectionException: Data source rejected establishment of connection, message from server: "Too many connections"
    報(bào)錯(cuò)很明顯,數(shù)據(jù)庫太多鏈接,應(yīng)該是關(guān)閉項(xiàng)目后資源沒有及時(shí)釋放。

    image.png

    解決方法如下:
    首先,重啟MySQL服務(wù)。
    進(jìn)入MySQL,輸入命令:
    show variables like 'max_connections'; 查看當(dāng)前最大連接數(shù)。
    最大連接數(shù)修改大一點(diǎn):
    set global max_connections=1000;
    注意事項(xiàng):使用上面的可以進(jìn)行臨時(shí)解決問題,想要一直開啟就需要去MySQL下面的my.ini文件里修改max_connections即可。
    MySQL安裝路徑查詢命令:
    進(jìn)入mysql命令行輸入:show variables like "%char%";

  2. Access denied for user 'root'@'localhost' (using password: Yes)
    到安裝的MySQL的目錄下,找my.ini文件;

在[mysqld]后添加skip-grant-tables(使用 set password for設(shè)置密碼無效,且此后登錄無需鍵入密碼)

skip-grant-tables #在my.ini,[mysqld]下添加一行,使其登錄時(shí)跳過權(quán)限檢查

  1. windows 配置mysql允許遠(yuǎn)程登陸。
    1.----連接Mysql (連接方式:mysql -u 你設(shè)置的用戶名 -p你設(shè)置的密碼 )
    2.----查看數(shù)據(jù)庫:show databases;我們會(huì)看到有一個(gè)叫做"mysql"的數(shù)據(jù)庫,這里我們輸入: use mysql 進(jìn)入'mysql'數(shù)據(jù)庫中
    3.----執(zhí)行 GRANT ALL PRIVILEGES ON . TO 'root'@'%' IDENTIFIED BY '你設(shè)置的密碼' WITH GRANT OPTION;
    若出現(xiàn)ERROR 1290 (HY000): The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement
    解決方案:
    執(zhí)行一次:mysql> flush privileges;
    然后再執(zhí)行:GRANT ALL Privileges....語句。
    重啟一下mysql服務(wù)
    注意:如果是云主機(jī),遠(yuǎn)程不能連接,那么可能是,防火墻規(guī)則沒有放行3306端口。我們要添加允許3306端口放行數(shù)據(jù)。


    image.png
  2. IDEA中mysql8.x注意時(shí)區(qū)設(shè)置問題,不設(shè)置容易出錯(cuò)。
    11 查看時(shí)區(qū)
    show VARIABLES like '%time_zone%'


    image.png

    time_zone: 表示 MySQL 采用的是系統(tǒng)的時(shí)區(qū)。也就是說,如果在連接時(shí)沒有設(shè)置時(shí)區(qū)信息,就會(huì)采用這個(gè)時(shí)區(qū)配置。
    12僅修改當(dāng)前會(huì)話的時(shí)區(qū),停止會(huì)話失效(CET)

 set time_zone = '+8:00';

13 修改全局的時(shí)區(qū)配置

    set globaltime_zone = '+8:00';
    flush privileges;

大多數(shù)時(shí)候用到13.

  1. com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Every derived table must have its own alias.別名
    ---做EduSystem項(xiàng)目時(shí),在ScoreDao.java中遇到的問題,它在連接oralce 12c不會(huì)出錯(cuò),這里是mysql出的問題。
String sql = "select courseno,coursename,case when score between 0 and 60 then '0-60' "+
                                        " when score between 60 and 70 then '60-70'"+
                                        " when score between 70 and 80 then '70-80'"+
                                        " when score between 80 and 90 then '80-90'"+
                                        " else '90-100' end as 分?jǐn)?shù)段,count(*)人數(shù) "+
                     " from (select A.courseno courseno,B.coursename coursename,A.score score from" +
                     " t_score A join t_course B on A.courseno=B.courseno where A.courseno='"+courseno+"')"+
                     " group by courseno,coursename,case when score between 0 and 60 then '0-60'"+
                                        " when score between 60 and 70 then '60-70'"+ 
                                        " when score between 70 and 80 then '70-80'"+ 
                                        " when score between 80 and 90 then '80-90'"+ 
                                        " else '90-100' end order by count(*)";

這句話的意思是說每個(gè)派生出來的表都必須有一個(gè)自己的別名。
一般在多表查詢時(shí),會(huì)出現(xiàn)此錯(cuò)誤。
因?yàn)?,進(jìn)行嵌套查詢的時(shí)候子查詢出來的的結(jié)果是作為一個(gè)派生表來進(jìn)行上一級(jí)的查詢的,所以子查詢的結(jié)果必須要有一個(gè)別名
把MySQL語句改成:select * from (select * from ……) as 別名;
改:注意,看下面代碼了最未尾的as xiong。

String sql = "select courseno,coursename,case when score between 0 and 60 then '0-60' "+
                                        " when score between 60 and 70 then '60-70'"+
                                        " when score between 70 and 80 then '70-80'"+
                                        " when score between 80 and 90 then '80-90'"+
                                        " else '90-100' end as 分?jǐn)?shù)段,count(*)人數(shù) "+
                     " from (select A.courseno courseno,B.coursename coursename,A.score score from" +
                    
 " t_score A join t_course B on A.courseno=B.courseno where A.courseno='"+courseno+"') as xiong".....
                    
  1. windows的cmd編碼問題,cmd默認(rèn)為gpk編碼,所以在cmd登入mysql后,插入中文數(shù)據(jù),不允許插入,查詢的中文也是亂碼。處理:登入數(shù)據(jù)庫后,寫下如下代碼,臨時(shí)有用。
>set names gpk;

幾個(gè)sql語句舉例。

----首選見以下幾個(gè)表
《1》t_student


image.png

《2》t_teahcer


image.png

《3》t_course
image.png

《4》t_score
image.png
  1. 查詢001號(hào)課程的每個(gè)分?jǐn)?shù)段有幾個(gè)人。
SELECT courseno,coursename,CASE WHEN score BETWEEN 0 AND 60 THEN '0-60'
                                         WHEN score BETWEEN 60 AND 70 THEN '60-70'
                                         WHEN score BETWEEN 70 AND 80 THEN '70-80'
                                         WHEN score BETWEEN 80 AND 90 THEN '80-90'
                                        ELSE '90-100' END AS 分?jǐn)?shù)段,COUNT(*) 人數(shù) 
                     FROM (SELECT A.courseno courseno,B.coursename coursename,A.score score FROM
                     t_score A JOIN t_course B ON A.courseno=B.courseno WHERE A.courseno=001) AS xiong
                     GROUP BY courseno,coursename,cas`t_student`e WHEN score BETWEEN 0 AND 60 THEN '0-60'
                                        WHEN score BETWEEN 60 AND 70 THEN '60-70'
                                        WHEN score BETWEEN 70 AND 80 THEN '70-80'
                                            WHEN score BETWEEN 80 AND 90 THEN '80-90'
                                        ELSE '90-100' END ORDER BY COUNT(*)

結(jié)果:


image.png
  1. 查詢0001號(hào)學(xué)生所選的課程號(hào)課程名,及所授課老師,課程成現(xiàn)。涉及三個(gè)表。
SELECT * FROM t_score A JOIN t_student B ON A.stuno=B.stuno JOIN t_course C ON
 A.courseno=C.`courseno` WHERE A.`stuno`=0001;

結(jié)果:


image.png
  1. 查詢所有課程名,結(jié)果集中不含重復(fù)的值。
SELECT DISTINCT(coursename) FROM t_course;

結(jié)果:


image.png

mysql數(shù)據(jù)的安裝配置

windows環(huán)境下

  1. mysql 8.x
https://dev.mysql.com/downloads/mysql/#downloads

image.png

[mysql安裝與遠(yuǎn)程登陸配置](http://www.itdecent.cn/p/a6801ba4b4d6

  1. mysql 5.x

數(shù)據(jù)庫與表操作

本示例是遠(yuǎn)程登陸數(shù)據(jù),首先本地要安裝了mysql,并配置了環(huán)境變量。

mysql -h 124.222.48.147 -u root -p    //回車
xiong                                          //密碼
  1. 創(chuàng)建/刪除數(shù)據(jù)庫
//創(chuàng)建數(shù)據(jù)庫
create database test_db;
SHOW create database test_db\G;   //查看數(shù)據(jù)庫定義
show databases;                                  //查看已有的數(shù)據(jù)庫

//刪除數(shù)據(jù)庫
DROP DATABASE database_name;

//顯示數(shù)據(jù)庫引擎類型
show engines \G                           //Support列的值表示某種引擎是否能使用,YES表示可以,NO表示不能,DEFAULT表示默認(rèn)為該引擎
show variables like 'storage_engine';

----InnoDB是事務(wù)型數(shù)據(jù)庫的首選引擎,支持事務(wù)的安全表(ACID),支持行鎖定和外鍵,MYSQL 5.5.5之后,InnoDB作為默認(rèn)存儲(chǔ)引擎 。如果數(shù)據(jù)表主要用來插入和查詢記錄,則 MyISAM引擎更好點(diǎn)。如果只是存放臨時(shí)數(shù)據(jù),數(shù)據(jù)量不大,并且不要求較高的安全性可用選用保存在內(nèi)存中的Memory引擎,只是存放一些中間結(jié)果。

  1. 創(chuàng)建數(shù)據(jù)表與相關(guān)配置
    創(chuàng)建表
create table <table_name>
(字段名1 數(shù)據(jù)類型 [列級(jí)別約束條件] [默認(rèn)值],
字段名2  數(shù)據(jù)類型 [列級(jí)別約束條件] [默認(rèn)值],
……
[表級(jí)別約束條件]
);

//創(chuàng)建表tb_emp1
mysql> create table tb_emp1
    -> (
    -> id INT(11),
    -> name  VARCHAR(25),
    -> deptId INT(11),
    -> salary FLOAT
    -> );

//創(chuàng)建表 tb_emp2 設(shè)了id為主鍵
create table tb_emp2
(
   id INT(11) PRIMARY KEY,
   name varchar(25),
   deptId INT(11),
   salary FLOAT
);
//或(也可用逗號(hào)隔開多字段聯(lián)合主鍵)
create table tb_emp2
(
    id INT(11) PRIMARY KEY,
    name varchar(25),
   deptId INT(11),
   salary FLOAT,
   primary key(id)
);

//外鍵約束,主要作用是保持?jǐn)?shù)據(jù)的一致性,完整性。
//外鍵約束用來在兩個(gè)表之間建立鏈接,它可以是一列或者多列。一個(gè)表可以有一個(gè)
//或多個(gè)外鍵,一個(gè)表的外鍵值可以為空,若不為空,則每一個(gè)外鍵值必須等于另一個(gè)表中的主鍵值。
//語法規(guī)則如下:
[constraint <外鍵名>] foreign key 字段名1[,字段名2,……] references <主表名> 主鍵列1[,主鍵列2.……] 
//例:創(chuàng)建表tb_dept1關(guān)聯(lián)到tb_emp3,主鍵id關(guān)聯(lián)到外鍵dpetId.

create table tb_emp3
(
   id INT(11) PRIMARY KEY,
   name varchar(22),
   deptId INT(11),
   salary FLOAT,
   constraint fk_emp3_dept1 foreign key(deptId) references tb_dept1(id)
);

create table tb_dept1
(
   id INT(11) primary key,
   name varchar(22) not null,
   location varchar(50)
);


//非空約束
name varchar(25) not null,

//唯一性約束
[constraint <約束名>] UNIQUE(<字段名>)
........
location varchar(50),
CONSTRAINT sth UNIQUE(name)
)

//默認(rèn)性約束,如某一表中性別‘男’較多時(shí),可設(shè)默認(rèn)值為‘男’
sex varchar(2) DEFAULT '男',

//設(shè)置表的字段值自動(dòng)增加
id INT(11) PRIMARY KEY AUTO_INCREMENT,

查看表結(jié)構(gòu)

describe 表名; 或 desc 表名;
show create table <表名\G>

修改表
一,表刪除操作須謹(jǐn)慎,因?yàn)閯h除表時(shí)沒有任提示信息,應(yīng)先備份再做刪除操作
二,并不是每個(gè)表都要一個(gè)主鍵,只有關(guān)聯(lián)時(shí)用到,有時(shí)因不須要有主鍵
三,并不是每個(gè)表都可以任意的選擇存儲(chǔ)引擎,如外鍵約束不可跨引擎。

//修改表名
ALTER TABLE <舊表名> RENAME [TO] <新表名>;

//修改數(shù)據(jù)類型
ALTER TABLE <表名> MODIFY <字段名> <數(shù)據(jù)類型>
例 :alter table tb_dept1 modify name varchar(30);

//添加字段
ALTER TABLE ,<表名> ADD <新字段名> <數(shù)據(jù)類型> [約束條件] [FIRST | AFTER 已存在字段名];   //默認(rèn)插入到最后列


//刪除字段
ALTER TABLE <tablename> DROP <字段名>;

//修改字段的排列位置
ALTER TABLE <表名> MODIFY <字段1> <數(shù)據(jù)類型> FIRST|AFTER <字段名2>;

//修改字段名
ALTER TABLE <表名> change <舊字段名> <新字段名>  <數(shù)據(jù)類型>
 
//更改表的存儲(chǔ)引擎 ,可以為每張表設(shè)定不同的引擎
//常用的引擎名:MyISAM,InnoDB,MEMORY(HEAP),BDB,CSV,ARCHIVE
ALTER TABLE <表名> ENGINE=<更改后的存儲(chǔ)引擎名>;


//刪除表的外鍵約束
ALTER TABLE <表名> DROP FOREIGN KEY <外鍵約束名>;

//刪除表
//1,刪除沒有被關(guān)聯(lián)的表
DROP TABLE [IF EXISTS] 表1,表2,表3.....n;
//2,刪除關(guān)聯(lián)表,首先,刪除父表,再刪除子表。而刪除父表之前,要冊(cè)除子表的外鍵約束。

//刪除表中所有的數(shù)據(jù)
delete from tablename;

數(shù)據(jù)類型

  1. 整數(shù)類型


    image.png

    分別點(diǎn)用1,2,3,4,8個(gè)字節(jié)存儲(chǔ)

  2. 浮點(diǎn)數(shù)類型
    MySQL中使用浮點(diǎn)數(shù)和定點(diǎn)數(shù)來表示小數(shù)。
    浮點(diǎn)類型:FLOAT、DOUBLE。
    定點(diǎn)類型:DECIMAL。占用m+2個(gè)字節(jié)
    例:create table temp(x FLOAT(5,1),y DOUBLE(5,1),z DECIMAL(5,1));
    都是保留一位小數(shù)。
  3. 字符串類型
    字符串類型用來存儲(chǔ)字符串?dāng)?shù)據(jù),除了可以存儲(chǔ)字符串?dāng)?shù)據(jù)之外,還可以存儲(chǔ)其它數(shù)據(jù),比如圖片和聲音的二進(jìn)制數(shù)據(jù)。
    CHAR、VARCHAR、BINARY、VARBINARY BLOB、TEXT、ENUM和SET。
    31。char與varchar固定長度,非固定長都為非二進(jìn)制字符串
    char(M)為固定長度字符串同,在定義時(shí)指定字符串列長。當(dāng)保存時(shí)在右側(cè)填充空格以達(dá)到指定的度.M表示長度,M的范圍是0-255個(gè)字符,其檢索時(shí)尾部空格被刪除,varchar(M),實(shí)際長度0~65535,實(shí)現(xiàn)存儲(chǔ)為M+1長度,一個(gè)結(jié)束符。
 insert into tmp4 values ('ab  ','ab  ');
mysql> select concat('(',ch,')'),concat('(',vch,')') from tmp4;
+--------------------+---------------------+
| concat('(',ch,')') | concat('(',vch,')') |
+--------------------+---------------------+
| (ab)               | (ab  )              |
+--------------------+---------------------+

insert into tmp4 values ('ab     ','ab     ');
 select concat('(',ch,')'),concat('(',vch,')') from tmp4;
+--------------------+---------------------+
| concat('(',ch,')') | concat('(',vch,')') |
+--------------------+---------------------+
| (ab)               | (ab  )              |
+--------------------+---------------------+

32。ENUM是一個(gè)字符串對(duì)象,其值為表創(chuàng)建時(shí)在列規(guī)定中枚舉的一列值。

create table tmp5(enm ENUM('first','second','third');

mysql> insert into tmp5 values('first'),('second'),('df');
ERROR 1265 (01000): Data truncated for column 'enm' at row 3   //沒有‘df’這個(gè)枚舉值
insert into tmp5 values('first'),('second');
+--------+
| enm    |
+--------+
| first  |
| second |
+--------+
  1. 二進(jìn)制
    前面講解了存儲(chǔ)文本的字符串類型,這一節(jié)將講解MySQL中存儲(chǔ)二進(jìn)制數(shù)據(jù)的數(shù)據(jù)類型
    BIT、BINARY、VARBINARY、TINYBLOB、
    BLOB、MEDIUMBLOB、LONGBLOB,
    41。BIT(M)類型
    BIT類型是位字段類型,M表示每個(gè)值的位數(shù),范圍為1~64.如果M被省略,默認(rèn)為1,如果為BIT(M)列分配的值的長度小于M位,在值的左邊用0填充。例如,為BIT(6)列分配一個(gè)值b'101',其效果與分配b‘000101‘相同。大于二進(jìn)制1111的數(shù)據(jù)是不能插入到BIT(4)中
 insert into tmp6 values(2),(6),(9);
mysql> select BIN(b+0) from tmp6;
+----------+
| BIN(b+0) |
+----------+
| 10       |
| 110      |
| 1001     |
| 1101     |
+----------+
  1. 日期與時(shí)間類型
    51。YEAR
    日期格式---YYYY,日期范圍:1901~2155 存儲(chǔ)需求:1字節(jié),(1)以4位字符串或數(shù)字格式表示YEAR年,例:輸入 ‘2020‘或2020,插入到數(shù)據(jù)庫的值均為2020.(2)以2位數(shù)字符串或數(shù)字格式表示的YEAR,范圍為‘00‘到‘99‘?!?0‘~‘69‘和‘70‘~’99’,范圍的值分別被轉(zhuǎn)換為2000~2069和1970~1999,數(shù)字1~69和70~99范圍的值分別被轉(zhuǎn)換為2000~2069和1970~1999,
    例:
create table tmp3(y YEAR);
INSERT INTO tmp3 values(2010),('2010');
+------+
| y    |
+------+
| 2010 |
| 2010 |
+------+

insert into tmp3 values('0'),('00'),('77'),('10');
+------+
| y    |
+------+
| 2000 |
| 2000 |
| 1977 |
| 2010 |
+------+

 insert into tmp3 values(77),(10);
| 1977 |
| 2010 |

52。TIME
時(shí)間類類里,在存儲(chǔ)時(shí)需要3個(gè)字節(jié)。格式為‘HH:MM:SS’.TIME類型的取值范圍為-838:59:59~838:59:59。(1)‘D HH:MM:SS'格式的字符串,可以使用下面任何一種語法,‘HH:MM:SS','D HH:MM','HH:MM','D HH'或‘SS’,為里D表示日,可以取值0~34之間的值,在插入數(shù)據(jù)庫時(shí),D被轉(zhuǎn)成小時(shí)保存,格式為“D*24+HH" (2)?!瓾HMMSS'格式的,沒有間隔符的字符串或HHMMSS數(shù)字格式的值,例如‘101112‘被理解為‘10:11:12’,但‘109712’是不合法的,因?yàn)榉譀]有大于59的。(3)CURRENT_TIME,NOW(),會(huì)自動(dòng)識(shí)別當(dāng)前時(shí)間TIME.
例:


 insert into tmp4 values('10:05:05'),('23:23'),('2 10:10'),('3 02'),('10');
+----------+
| t        |
+----------+
| 10:05:05 |
| 23:23:00 |
| 58:10:00 |
| 74:00:00 |
| 00:00:10 |
+----------+


 insert into tmp4 values('101112'),('111213'),('0');

+----------+
| t        |
+----------+
| 10:11:12 |
| 11:12:13 |
| 00:00:00 |
+----------+

insert into tmp4 values(CURRENT_TIME),(now());

53。DATE
該類型用在僅需要日期值時(shí),沒有時(shí)間部分,存儲(chǔ)需要3個(gè)字節(jié)(1),以‘YYYY-MM-DD’或‘YYYYMMDD’字符串表示的日期,取值范圍'1000-01-01'~'9999-12-3'(2)'YY-MM-DD'或'YYMMDD',二位年份參考前面的YEAR類型講解(3),使用CURRENT_DATE或NOW(),插入當(dāng)前系統(tǒng)的日期
----Mysql允許“不嚴(yán)格”語法:任何標(biāo)點(diǎn)符號(hào)都可以用作日期部分之間的間隔符。例:‘99-11-31' '99.11.31','99/11/31','99@11@31"都是等價(jià)的。

 insert into tmp1 values (990909),(000101),(111111);
+------------+
| d          |
+------------+
| 1999-09-09 |
| 2000-01-01 |
| 2011-11-11 |
+------------+

54。DATETIME
DATATIME類型用在需要同時(shí)包含日期和時(shí)間信息的值,在存儲(chǔ)時(shí)需要8個(gè)字節(jié)。日期格式'YYYY-MM-DD HH:MM:SS'(1).''YYYY-MM-DD HH:MM:SS'或者‘YYYYMMDDHHMMSS’取值范圍是'1000-01-01 00:00:00'到‘9999-12-3 23L59:59‘(2)?!甕Y-MM-DD HH:MM:SS'或者‘YYMMDDHHMMSS'(3)。YYYYMMDDHHMMSS或者YYMMDDHHMMSS

insert into tmp2 values('1998-01-17 08:08:08'),('19980117080808');
+---------------------+
| d                   |
+---------------------+
| 1998-01-17 08:08:08 |
| 1998-01-17 08:08:08 |

 insert into tmp2 values('99-09-09 09:09:09'),('990909090909');
| 1999-09-09 09:09:09 |
| 1999-09-09 09:09:09 |
+---------------------+

insert into tmp2 values (NOW());           //插入當(dāng)前日期

55。TIMESTAMP
顯示格式與DATETIME相同,顯示寬度固定在19個(gè)字符,存儲(chǔ)需要4個(gè)字節(jié),但它的取值范圍為'1970-01-01 00:00:01' UTC~ '2038-01-19 03:14:07` UTC.UTC世間標(biāo)準(zhǔn)時(shí)間。TIMESTAMP值的存儲(chǔ)是以UTC格式保存的,存儲(chǔ)時(shí)對(duì)前時(shí)區(qū)進(jìn)行轉(zhuǎn)換,檢索時(shí)再轉(zhuǎn)換回回當(dāng)前時(shí)區(qū)。即查詢時(shí),根據(jù)當(dāng)前時(shí)區(qū)的不同,顯示的時(shí)間值是不同的

insert into tmp3(NOW());
+---------------------+
| ti                  |
+---------------------+
| 2022-12-08 20:00:37 |
+---------------------+
//我們中國所在的時(shí)區(qū)為東8區(qū),下面我們修改一下時(shí)區(qū)為東10區(qū),再看看結(jié)果
 set time_zone='+10:00';
+---------------------+
| 2022-12-08 22:00:37 |
+---------------------+

常見運(yùn)算符介紹

運(yùn)算符,下面是按高到低的優(yōu)先級(jí)寫的。
!
-負(fù)號(hào),~位反轉(zhuǎn)
*,/,%(求余)
+,-
<<.>>
&
|
=,<=>,>=,>,<=,<,<>,!=,IS,LIKE,REGEXP,IN,LEAST(返回最小值)
BETWEEN,CASE,WHEN,THEN,ELSE
NOT
&& ,AND
XOR
||,OR
=(賦值),:=,逗號(hào)

  1. 算術(shù)運(yùn)算符
    例:創(chuàng)建表tmp7,定義數(shù)據(jù)類型為INT的字段num,插入值64,對(duì)num值進(jìn)行算術(shù)運(yùn)算。
create table tmp7(num  int);
insert into tmp7 values(64);
select num,num+10,num-3+5,num+5-3,num+36.5 from tmp7;
+------+--------+---------+---------+----------+
| num  | num+10 | num-3+5 | num+5-3 | num+36.5 |
+------+--------+---------+---------+----------+
|   64 |     74 |      66 |      66 |    100.5 |
+------+--------+---------+---------+----------+
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Create database語句 ? Create database語句是在MySQL實(shí)例上創(chuàng)建一個(gè)指定名稱的數(shù)...
    碼農(nóng)工號(hào)9527閱讀 660評(píng)論 0 1
  • 數(shù)據(jù)庫創(chuàng)建刪除 創(chuàng)建刪除表 數(shù)據(jù)插入 WHERE子句 where子句一般后面跟著條件語句: 更新語句 UPDATE...
    轉(zhuǎn)身一世鉛華盡閱讀 334評(píng)論 0 0
  • 首先在mysql數(shù)據(jù)庫中新建兩張表,并且插入數(shù)據(jù)。 MySql(準(zhǔn)備)—mysql使用存儲(chǔ)過程快速插入百萬條數(shù)據(jù)[...
    小胖學(xué)編程閱讀 1,071評(píng)論 0 7
  • 一、基本概念 數(shù)據(jù)庫術(shù)語 數(shù)據(jù)庫(database) - 保存有組織的數(shù)據(jù)的容器(通常是一個(gè)文件或一組文件)。 數(shù)...
    cisonRen閱讀 1,388評(píng)論 0 2
  • 數(shù)據(jù)庫排名:Oracle(關(guān)系型)MySQL(關(guān)系型)SQLServer(關(guān)系型)PostgreSQL(關(guān)系型)M...
    Devil灬閱讀 352評(píng)論 0 0

友情鏈接更多精彩內(nèi)容