MySQL與MariaDB學習筆記

onephone發表於2017-10-25

本文是《MySQL與MariaDB學習指南》的簡要學習筆記,方便日後查詢和回憶!
原書容較為基礎,但夠用了,尤其常用函式和資料匯入匯出寫的很不錯! 適合初學者以及對mysql瞭解不用很深的人(僅會用)! 原書不涉及任何sql的優化!
發現了書中兩處錯誤,已提交勘誤!
進階讀物《深入理解MariaDB和MySQL》
作者網站mysqlresources.com有很多資料。

0x01 準備

  • 自己沒有安裝相關工具,使用了docker mariadb 映象
  • 相關命令如下
    • docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root --name mariadb -d mariadb:latest
    • docker exec -it mariadb bash
    • docker start mariadb
  • 登陸說明

    bash
    root@b2659b21f321:/# mysql -uroot -proot # 預設使用者名稱和密碼為root
    Welcome to the MariaDB monitor. Commands end with ; or \g. # 命令要以分號(;) 或斜線 +g(\g)結尾
    Your MariaDB connection id is 10 # 本次連線識別符號
    Server version: 10.2.7-MariaDB-10.2.7+maria~jessie mariadb.org binary distribution
    Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. # 可清除之前快取的輸入一半的mysql命令
    MariaDB [(none)]>

  • help 幫助命令, 最有用的 help contents

    • help
    • help Data Manipulation
    • help SHOW DATABASES
  • prompt 可修改提示符
  • 大小寫區別
    • MySQL 不區分關鍵字(如 SHOW)的大小寫,所以可以 用 show 甚至 sHoW
    • 資料庫、表和列的名字卻可能是區分大小寫的,尤其是在那些大小寫敏感的作業系統上,如Mac OS X或Linux
  • 使用者自定義變數, 以 @ 開頭的名字,再用 = 連線上一個值,或者一個表示式,又或者一條返回單個 值的 SQL 語句, 即SET @fav_site_total =
  • show tables from msyql; 顯示mysql資料庫中的所有表
  • describe mysql.user;
  • 建立資料庫和表
    • CREATE SCHEMA swf == CREATE DATABASE swf
    • CREATE DATABASE swf2 CHARACTER SET latin1 COLLATE latin1_bin; # MySQL 資料的儲存方式是二進位制拉丁字元
    • 表名可以是 SQL 保留字以外的任何東西。事實上,用保留字也可以,但需要加上引號以作區分
    • AUTO_INCREMENT 選項告訴 MySQL 此列的值是自增的
    • TEXT型別,即長度可變,但最多65 535位元組
    • 如果你能確定某列內容的長度,那就用 CHAR,否則用 VARCHAR
    • UNIQUE, 會截短顯示為 UNI
    • ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_bin, 首先是表型別,或者說是該表使用的儲存引擎的型別; 剩下兩個是表的預設字符集(latin1)和預設校對方式(latin1_bin)
    • 校對方式,則可選 latin5_turkish_ci,它會根據土耳其語的字母表來排序
    • BLOB 二進位制大物件
  • 備份資料庫 mysqldump --user='russell' -p rookery birds > /tmp/birds.sql
  • 匯入資料庫 mysql --user='russell' -p rookery < rookery-ch2-end.sql
  • CREATE TABLE test.birds_new LIKE birds; 僅複製表結構
  • CREATE TABLE birds_new_alternative SELECT * FROM rookery.birds; 複製表結構和表資料

0x02 相關操作

  • ALTER TABLE birds ADD COLUMN test INT
  • ALTER TABLE birds_new ADD COLUMN wing_id CHAR(2);
  • ALTER TABLE birds_new ADD COLUMN wing_id CHAR(2) AFTER family_id; # 在特定的列之後加入一列
  • ALTER TABLE birds_new DROP COLUMN wing_id;
  • ALTER TABLE birds_new ADD COLUMN bill_id CHAR(2) AFTER body_id, ADD COLUMN endangered BIT DEFAULT b'1' AFTER bill_id;可同時新增多列
  • ALTER TABLE birds_new CHANGE COLUMN common_name common_name VARCHAR(255); 在使用CHANGE COLUMN時,就算只想修改該列的某一方面, 也需要完整地宣告整個新列。
  • MODIFY COLUMN子句的語法只要求輸入一次列名, MODIFY COLUMN是不能用來 改列名的

    sql
    ALTER TABLE birds_new
    MODIFY COLUMN endangered
    ENUM('Extinct',
    'Extinct in Wild',
    'Threatened - Critically Endangered',
    'Threatened - Endangered',
    'Threatened - Vulnerable',
    'Lower Risk - Conservation Dependent',
    'Lower Risk - Near Threatened',
    'Lower Risk - Least Concern')
    AFTER family_id;

  • SHOW COLUMNS FROM birds_new LIKE 'endangered' \G 結果僅顯示 endangered 列的設定

    • SHOW FULL COLUMNS顯示更全的資訊
  • ALTER TABLE birds_new ALTER conservation_status_id DROP DEFAULT; 修改預設值的設定
  • SELECT auto_increment FROM information_schema.tables WHERE table_name = 'birds';
  • ALTER TABLE birds AUTO_INCREMENT = 10;
    • 這個命令雖說是更改 bird_orders 表,但實際修改的是伺服器上儲存 AUTO_INCREMENT 值的表 (information_schema資料庫中的)
  • 重新命名一個表 RENAME TABLE table1_altered TO table1;
  • 將一個表移動到另一個資料庫中 RENAME TABLE rookery.birds TO rookery.birds_old, test.birds_new TO rookery.birds;
  • SHOW TABLES FROM mysql LIKE 'plugin'; 或者 SHOW TABLES IN rookery LIKE 'birds%';
  • SHOW INDEX FROM birdwatchers.humans \G
  • ALTER TABLE birdwatchers.humans ADD INDEX human_names (name_last, name_first); 新增索引
  • EXPLAIN語句返回的資訊中, possible_keys域表示可能用到的鍵, key 域表示確實用到的鍵
  • ALTER TABLE conservation_status DROP PRIMARY KEY, CHANGE status_id conservation_status_id INT PRIMARY KEY AUTO_INCREMENT;
  • SHOW WARNINGS \G
  • DELETE FROM bird_families WHERE family_id = 101;
  • INSERT INTO ...... VALUES ......
  • INSERT IGNORE INTO ...... 指示伺服器忽略所有錯誤,並插入那些沒有產生錯誤的行, 接下來可以通過SHOW WARNINGS 顯示那些有問題的行
  • UPDATE ....... SET ...... WHERE ......
  • REPLACE INTO ...... VALUES ......REPLACE INTO ...... SELECT ......
    • REPLACE 語句可用於替換含有重複鍵的整行資料,或新增原表中所沒有的資料。
    • 整行替換
  • INSERT LOW_PRIORITY INTO bird_sightings
    • InnoDB 引擎的表不支援 LOW_PRIORITYHIGH_ PRIORITY,因為 InnoDB 只鎖定相關的行而不鎖定整個表,所以這兩個選項對它沒有意義。
  • LIMIT 子句帶了兩個值:一個是開始位置,一個是行數
  • 如果列的別名就是一個單詞,那麼沒有必要加引號。否則,要加。另外,保留字(如 Order)也要加引號
  • 在 ORDER BY 中不能使用列的別名,但表的別名則可以。
  • REGEXP正則匹配 WHERE common_name REGEXP 'Great|Least' AND common_name NOT REGEXP 'Hawk-Owl'
  • 別名關鍵字 AS 可以可無!
  • UPDATE humans SET formal_title = SUBSTRING(formal_title, 1, 2);
  • 在MySQL使用UPDATE的多表語法時,不能帶有ORDER BY或LIMIT——但在 UPDATE 單表時就可以

    sql
    UPDATE prize_winners, humans
    SET winner_date = CURDATE()
    WHERE winner_date IS NULL
    AND country_id = 'uk'
    AND prize_winners.human_id = humans.human_id
    ORDER BY RAND() # 隨機
    LIMIT 2; # 只更新兩行

  • INSERT...ON DUPLICATE KEY UPDATE...

    sql
    INSERT INTO humans
    (formal_title, name_first, name_last, email_address, better_birders_site)
    VALUES('Mr','Barry','Pilson', 'barry@gomail.com', 1),
    ('Ms','Lexi','Hollar', 'alexandra@mysqlresources.com', 1),
    ('Mr','Ricky','Adams', 'ricky@gomail.com', 1)
    ON DUPLICATE KEY
    UPDATE better_birders_site = 2; # 在重複的行上設定那個欄位為2

  • 多表刪除操縱, DELETE FROM table[, table] USING table[, . . . ] [WHERE condition];

    sql
    DELETE FROM humans, prize_winners
    USING humans JOIN prize_winners
    WHERE name_first = 'Elena'
    AND name_last = 'Bokova'
    AND email_address LIKE '%yahoo.com'
    AND humans.human_id = prize_winners.human_id;

  • 連線時在左表(humans)中找不到對應行,右表(prize_winners)的資料也會被刪除

    sql
    DELETE FROM prize_winners
    USING humans RIGHT JOIN prize_winners
    ON humans.human_id = prize_winners.human_id
    WHERE humans.human_id IS NULL;

  • 因為使用 UNION 時,MySQL 只會取第一個 SELECT 的域名作為最終結果集的 標題,而之後的 SELECT 的域名都會被忽略

  • 編寫SQL語句時,連線條件與篩選條件最好分開!
  • 使用 USING 時,連線條件中的列必須是在兩表中都 存在的
  • 不要把 USING...JOINJOIN...USING 搞混了

    sql
    SELECT book_id, title, status_name
    FROM books
    JOIN status_names ON(status = status_id);
    SELECT book_id, title, status_name
    FROM books
    JOIN status_names USING(status_id);
    UPDATE birds
    LEFT JOIN conservation_status USING(conservation_status_id)
    JOIN bird_families USING(family_id)
    SET birds.conservation_status_id = 9
    WHERE bird_families.scientific_name = 'Ardeidae'
    AND conservation_status.conservation_status_id IS NULL;

  • 動態列

  • 子查詢
    1. 標量子查詢:只返回一個值
    2. 列子查詢
    3. 行子查詢
    4. 表子查詢
    5. 自查詢效能

0x03 常用函式

文字作為引數時,需要使用引號。
列作為引數時,不要用引號——否則列名會被當成文字。如果列名是保留字或含有 可能引起問題的字元,可用反引號標示列名。
如果字串函式返回的值過長(即返回了太多的字串),超出了系統限制(max_allowed_packet選項),MySQL 就會返回 NULL。
有些引數用於指定字串中字元的位置。字串第一個字元的位置是1,不是0。 當需要從後往前數時(有些函式允許這麼做),最後一個字元的位置是 -1。
有些引數用於表示字串長度。如果用到小數,MySQL就會將其四捨五入為最接 近的整數。

  1. 字串函式

    • 拼接 CONCAT(), CONCAT_WS('|', ...)指定分隔符
      • mysql -p --skip-column-names -e "" > tmp.txt, --skip-column-names 隱藏列名
    • 大小寫 LCASE(common_name)LOWER(), UCASE(bird_families.scientific_name)UPPER()
    • 引號 QUOTE(common_name) 接受字串輸入,然後將其用單引號包圍, 會對某些字 符進行轉換, 包括單引號、反斜槓、空(零)位元組,以及 Ctrl-Z 字元
    • 修剪 RTRIM(name_first), LTRIM(), TRIM()
    • 填充 RPAD(common_name, 20, '.' ), LPAD(), SPACE() 在 網頁上顯示的話,則要用 &nbsp;(不換行空格)來填充
    • 抽取字元 LEFT(prospect_name, 2), MID(prospect_name, 5, 25), RIGHT(prospect_name, 25)
      • SUBSTRING(prospect_name, 1, 2) 第三個參數列示個數
      • SUBSTRING(prospect_name FROM 5 FOR 25), 其中25 代表抽取長度
      • SUBSTRING(prospect_name, -25)
    • 抽取元素 SUBSTRING_INDEX(prospect_name, '|', 1), SUBSTRING_INDEX(prospect_name, '|', -1) 第三個參數列示抽取個數
    • 搜尋 LOCATE('Avocet', common_name) 返回Avocet子字串第一次出現的地方
  2. 日期和時間函式

    • 儲存日期的 DATE,儲存時間的 TIME,將日期和時 間一起儲存的 DATETIME 和 TIMESTAMP,以及儲存年份的 YEAR
    • NOW() 有幾個同義詞:CURRENT_TIMESTAMP()LOCALTIME()LOCALTIMESTAMP()
      • NOW() 所返回的日期和時間是它所在的 SQL 語句開始執行時的日期和時間
      • SYSDATE(),它返回的是自身被執行時的那個時間點(不是整條語句的結束時間)
      • SELECT NOW(), SLEEP(4) AS 'Zzz', SYSDATE(), SLEEP(2) AS 'Zzz', SYSDATE();
    • 獲取時間 CURDATE( ), CURTIME( ), UNIX_TIMESTAMP()
    • 抽取時間
      • HOUR(time_seen), MINUTE(time_seen), SECOND(time_seen)
      • YEAR()、MONTH() 和 DAY()
      • MONTHNAME() 和 DAYNAME()
      • EXTRACT(), EXTRACT(YEAR_MONTH FROM time_seen), EXTRACT(HOUR_MINUTE FROM time_seen), EXTRACT(MONTH FROM time_seen)
    • 格式化時間
      • DATE_FORMAT(time_seen, '%W, %M %e, %Y')
      • TIME_FORMAT(time_seen, '%l:%i %p')
      • SELECT GET_FORMAT(DATETIME, 'ISO'), GET_FORMAT(DATE, 'ISO') 可以檢視時間的標準格式
    • 時區
      • SHOW VARIABLES LIKE 'time_zone';
      • CONVERT_TZ() 接受三個引數:日期和時間,來自哪個時區,想轉換成哪個時區
      • mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -p -u root mysql 安裝時區檔案
      • 設定時區 SET GLOBAL time_zone = 'GMT';, default-time-zone='GMT'
    • 時間加減
      • DATE_ADD()DATE_SUB(), 語法一樣:第一個引數是要修改的日期,第二個引數是時間量, 時間量的寫法是:在 INTERVAL 關鍵字後接上數字和單位(例如INTERVAL 1 DAY)
      • DATE_ADD(membership_expiration, INTERVAL 3 MONTH), DATE_ADD(membership_expiration, INTERVAL -1 YEAR)
      • DATE_SUB(membership_expiration, INTERVAL 1 YEAR)
      • 可以用組合時間,一天兩小時之後 DATE_ADD(time_seen, INTERVAL '1 2' DAY_HOUR)
      • TIME_TO_SEC()SEC_TO_TIME()
      • PERIOD_ADD(), 接受兩個引數,第一個是日期,第二個是想要增加的月的數量, 它接受的引數不是日期型別,而是字串類 型,同時,返回值也是字串
      • PERIOD_ADD( EXTRACT(YEAR_MONTH FROM CURDATE()), -3)
      • DATE_ADD() 的別名 ADDDATE(), DATE_SUB() 的別名 SUBDATE())
    • 季度顯示 QUARTER(CURDATE())
    • 比較日期 DATEDIFF() 和 TIMEDIFF()
  3. 聚合函式和數值函式
    • TIME_TO_SEC(), AVG(), MIN(avg_time), MAX(avg_time)
    • STDDEV() 和 VARIANCE() 標準差、方差
    • 拼接同組的值, GROUP_CONCAT(), 可以把一個組所有的值拼接成一個以逗號分隔的串
    • 能以某種方式改變數字的函式叫作數值函式
      • 四捨五入 ROUND(),
      • 上舍入, 下舍入 FLOOR(), CEILING()
      • 截斷, 只想去掉小數,那可以用 TRUNCATE()
      • 取絕對值 ABS()
      • 判斷正負 SIGN()
      • POWER(2, 8) 會返回2的8次方,即256; PI() 會返回π,即3.141593

0x04 許可權管理

使用者賬號: 使用者名稱與主機的組合”

  1. 使用者賬戶

    • SHOW GRANTS FOR 'lena_stankoska';, SHOW GRANTS FOR 'lena_stankoska'@localhost \G
    • GRANT ALL ON rookery.* TO 'lena_stankoska'@'localhost';
    • DROP USER 'lena_stankoska'@'localhost';, DROP USER 'lena_stankoska'@'%';
    • 建立使用者&賦予許可權
      • CREATE USER 'lena_stankoska'@'localhost' IDENTIFIED BY 'her_password_123';
      • GRANT USAGE ON *.* TO 'lena_stankoska'@'lena_stankoska_home' IDENTIFIED BY 'her_password_123';
      • SELECT PASSWORD('her_password_123');, 從 MySQL 5.6 版本開始,包含 PASSWORD 的語句不會被記錄
    • ** GRANT和REVOKE語句中可用的許可權 -- P197 **
    • 許可權操作指令碼 -- P201
    • 限制訪問特定的列 GRANT SELECT (human_id, formal_title) ON birdwatchers.humans TO 'lena_stankoska'@'lena_stankoska_home';
  2. 備份和匯入賬號

    • 在插入資料時,還需要 LOCK TABLES 許可權來鎖住表。
    • 需要CREATE和INDEX許可權來分別建立表和索引。
    • 因為dump檔案可能包含設定校對集的語句,所以需要ALTER許可權。
    • 基於Lena Stankoska用來恢復表的方法,她可能還想將資料恢復到臨時表。這樣的話,
      則需要 CREATE TEMPORARY TABLES 許可權。(臨時表會在連線關閉時被刪掉。)
    • 如果資料庫有檢視或觸發器,則需要 CREATE VIEW 和 TRIGGER 許可權。
  3. 批量匯入的賬號
    • LOAD DATA INFILE 語句需要 FILE 許可權
    • FILE 許可權存在安全風險,因為它可以讀取伺服器上 MySQL 能檢視的任何檔案, 但可以通過 secure_file_priv 變數來限制只能讀取某個目錄
    • FILE 許可權不能指定用於某個庫或某個元件,它是一個全域性許可權, 可以將資料匯入任何資料庫,並從任何資料庫中匯出資料, 其中包括 mysql 資料庫。
  4. 用於授權的賬號
    • 使其能建立並授權其他使用者賬號,需要在 GRANT 中加上 GRANT OPTION 子句
    • GRANT ALL PRIVILEGES ON rookery.* TO 'admin_granter'@'localhost' IDENTIFIED BY 'avocet_123' WITH GRANT OPTION;
  5. 回收許可權
    • REVOKE ALL PRIVILEGES ON rookery.* FROM 'michael_stone'@'localhost';
    • REVOKE ALTER ON rookery.* FROM 'admin_restore'@'localhost';
    • 某個使用者可能對應多個賬號
      • MySQL沒有SHOW USERS語句, 因此只能SELECT User, Host FROM mysql.user WHERE User LIKE '%michael%' OR User LIKE '%stone%';
    • 在刪除賬號時,如果該賬號已登入,並且有活動中的會話,那麼這些會話都不會被停止
      • 強制終止 SHOW PROCESSLIST;獲取會話識別符號,如1482, 接著使用KILL 1482;
    • SHOW PROCESSLIST 和 KILL 分別需 要PROCESS和SUPER許可權。
  6. 更改使用者密碼
    • 使密碼過期 ALTER USER 'admin_granter'@'localhost' PASSWORD EXPIRE;
    • 修改密碼 SET PASSWORD FOR 'admin_granter'@'localhost' = PASSWORD('some_pwd_123');
    • 忘記root密碼的方法 -- P208
      1. 新建一個文字檔案,輸入以下內容,注意一行寫一條語句:
      2. UPDATE mysql.user SET Password=PASSWORD('new_pwd') WHERE User='root';
      3. FLUSH PRIVILEGES;
      4. 將該檔案起名為rt-reset.sql,並放在受保護的目錄中。然後用 --init-file, 啟動 MySQL,如下
      5. mysqld_safe --init-file=/root/rt-reset.sql &
      6. 啟動後,登入 MySQL,看看密碼是否已經修改。可以使用這種方式多次修改密碼。改完之後,刪除 rt-reset.sql
  7. 角色
    • CREATE ROLE 'admin_import_role';
    • GRANT FILE ON *.* TO 'admin_import_role'@localhost;
    • 啟用角色 SET ROLE 'admin_import_role'; ... , SET ROLE NONE;

0x05 備份和恢復

  1. mysqldump --> P214
    • 備份所有資料庫 mysqldump --user=admin_backup --password --lock-all-tables --all-databases > /data/backups/all-dbs.sql
    • MySQL 的工具過去常常提供一些簡短形式的選項,比如用 -u 代表 --user 但是這些簡短形式現在已不被推薦,甚至在未來的版本中可能會被取消。
    • 用 mysqldump 給 InnoDB 表或其他事務型的表做備份時,最好加上 --single- transaction 選項。這能提高資料的一致性。
    • 加上 `--ignore-table=mysql.user, 可以忽略mysql.user資料庫
    • --skip-extended-insert 將多個插入語句擴充套件成一個, P216 有詳細欄位說明
    • /*! 是 MySQL 和 MariaDB 的條件性語句
    • dump檔案說明 P215
    • 備份指令碼 P221
  2. 恢復備份
    • mysql --user=admin_restore --password < rookery.sql
    • 恢復表
      • 修改dump檔案
      • 用臨時資料庫來做恢復
      • 使用受限的使用者賬號: 該賬戶支隊要回復的表有許可權,但該方法比較危險
      • 只回復某些行或某些列: 藉助臨時表
  3. 二進位制日誌
    • 時間點恢復的前提條件是,你開啟了二進位制日誌, SHOW BINARY LOGS;
    • 開啟二進位制日誌的方法
      • 修改 MySQL 配置檔案(可能是 my.cnf 或 my.ini),在 [mysqld] 那一部分中,加入以下語句:
      • log-bin
      • binlog-ignore-db=mysql
      • 重啟 MySQL,以使配置生效, SHOW MASTER STATUS檢視日誌是否生效
    • mysqlbinlog 抽取當前二進位制日誌的內容並將其儲存到文字檔案
      • SHOW VARIABLES WHERE Variable_Name LIKE 'datadir'; 檢視日誌檔案存放目錄
      • mysqlbinlog --database=rookery /data/mysql/mysqlresources-bin.000002 > recovery-research.txt
      • 從二進位制日誌中抽取語句並執行 P232
      • 二進位制檔案中 BEGIN 和 COMMIT 是事務開始和結束的標誌
      • 所謂事務,通常就是指一組同時執行且彼此相關的 SQL 語句。它只在事務性表(比如 InnoDB)上可用,而在非事務性表(比如 MyISAM)上不可用
      • 按照position恢復 mysqlbinlog --database=rookery --start-position="1284889" --to-last-log ...
      • 按照時間點恢復 mysqlbinlog --database=rookery --stop-datetime="140916 13:10:24" ...
      • mysqlbinlog --database=rookery --start-datetime="140916 13:10:29" --to-last-log
      • 二進位制日誌也可用於做備份,即 MySQL 複製, 主從備份即是!
  4. 備份策略 P234

0x06 匯入匯出

  • 匯入 LOAD DATA INFILE

    ```sql
    -- 統一匯入
    LOAD DATA INFILE '/tmp/Clements-Checklist-6.9-final.csv'
    INTO TABLE rookery.clements_list_import
    FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' -- 指定域用的是雙引號
    IGNORE 1 LINES; -- 忽略指定的行數
    -- 匯入對應的域
    LOAD DATA INFILE '/tmp/Clements-Checklist-6.9-final.csv' INTO TABLE rookery.clements_list_import
    FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
    IGNORE 1 LINES
    (id, change_type, @niente, @niente,
    @niente, bird_order, family, @niente,
    @niente, @niente, @niente, @niente); -- 那些不想要的域則被匯入了臨時變數 @niente
    -- 設定列(family)
    LOAD DATA INFILE '/tmp/Clements-Checklist-6.9-final.csv' INTO TABLE rookery.clements_list_import
    FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
    IGNORE 1 LINES
    (id, change_type, @niente, @niente,
    @niente, bird_order, @family, @niente,
    @niente, @niente, @niente, @niente, @niente)
    SET family = SUBSTRING(@family, 1, LOCATE(' (', @family) );
    -- 比較全的
    LOAD DATA INFILE '/tmp/birdwatcher-prospects.csv'
    INTO TABLE birdwatchers.birdwatcher_prospects_import
    FIELDS TERMINATED BY '|' ENCLOSED BY '"' ESCAPED BY '\'
    LINES STARTING BY '[' TERMINATED BY ']\r\n' -- STARTING BY 行以左中括號開頭; TERMINATED BY指定行由右中括號、回車和換行符結尾
    IGNORE 1 LINES
    (prospect_name, prospect_email, prospect_country);

    ```

  • 忽略錯誤,LOAD DATA INFILE ... IGNORE INTO TABLE ...

  • 替換,LOAD DATA INFILE ... REPLACE INTO TABLE ...
  • 使用mysqlimport, 所有的選項與LOAD DATA INFILE的一樣,只是變成了小寫,並以兩個橫槓開頭, 但是沒有--lines-starting-by選項,所以支援不夠

    sql
    mysqlimport –user='marie_dyer' --password='sevenangels' \
    --replace --low-priority --ignore-lines='1' \
    --fields-enclosed-by='"' --fields-terminated-by='|' --fields-escaped-by='\\' \ --lines-terminated-by=']\r\n' \
    --columns='prospect_name, prospect_email, prospect_country' \
    birdwatchers '/tmp/birdwatcher_prospects_import.csv'

  • 沒有FILE許可權也能匯入資料 P253

0x07 程式設計介面

P258

  1. pythoni 可使用 mysql.connector
  2. sql注入 -- 推薦使用佔位符?,而不是字元拼接,前者會對傳入的引數轉義

    sql
    my $sql_stmnt = "SELECT human_id,
    CONCAT(name_first, SPACE(1), name_last) AS full_name,
    membership_expiration
    FROM humans
    WHERE name_last LIKE ?"; -- 問號是佔位符
    $sql_stmnt = "SELECT common_name, scientific_name
    FROM birds
    WHERE common_name LIKE '%$search_parameter%'" -- 字元拼接

相關文章