<h1> MySQL Notes </h1> Tinf's note on [Coursera](https://www.coursera.org/learn/intro-sql/) <h2> Prepare Env (on Ubuntu) </h2> <h3> Install MySQL </h3> ```console sudo apt update && sudo apt install mysql-server ``` <h3> Put server on </h3> ```zsh sudo service mysql start ``` <h3> Log in to the server </h3> ```zsh mysql -u root -p ``` > 預設密碼為root <h3> 2. WHERE </h3> <h4> 創建所有關聯式資料集臨時表後再過濾資料 </h4> <h2> Basic operations (On MySQL-cli) </h2> <h3> 顯示Server上所有資料庫 </h3> ```sql SHOW DATABASES; ``` <h3> 創建資料庫 </h3> ```sql CREATA DATABASES "Database's name"; ``` <h3> 選擇使用的資料庫 </h3> ```sql USE "Database's name"; ``` <h3> 創建表格 </h3> ```sql CREATE TABLE "Table's name"( "Column's name" "DataType" ("limmit"), "Column's name" "DataType" ("limmit"), . . . ); ``` <h3> 顯示表格內各欄位設定 </h3> ```sql DESCRIBE "Table's name"; ``` <h3> 新增資料至表格 </h3> ```sql INSERT INTO "Table's name" ("column1", "column2", ...) VALUES ("Data1", "Data2", ...); ``` <h3> 從表格刪除資料(有條件) </h3> ```sql DELETE FROM "Table's name" (WHERE "Condition"); ``` <h3> 更新表格內資料 </h3> ```sql UPDATE "Table's name" SET "Target column's name" = "New content" WHERE "Target column's name" = "Target content" ``` <h3> 顯示表格內資料(帶條件)(排序)(特定關鍵字) </h3> ```sql SELECT * FROM "Table's name" (WHERE "condition") (ORDER BY "Column's name") (WHERE "Column's name" LIKE '%"Keyword"%'); ``` <h3> 計算表格內資料筆數(帶條件) </h3> ```sql SELECT COUNT(*) FROM "Table's name" (WHERE "Condition"); ``` <h3> 修改Table內Column </h3> ```sql ALTER TABLE "Table's name" DROP/ADD COLUMN "column's name"; ``` --- <h2> Data Types </h2> <h3> String </h3> <h4> Understand character sets and indexable for searching </h4> * CHAR : Allocates the entire space (for small strings and unknow length) * VARCHAR : Depending on the date length (less space) <h4> Usage: normal string data </h4> <h3> Text </h3> <h4> Have a character set but not used with index or sorting and can only prefix </h4> * TINYTEXT : up to 255 characters * TEXT : up to 65K * MEDIUMTEXT : up to 16M * LONGTEXT : up to 16G <h4> Usage: paragraphs or HTML pages </h4> <h3> Binary Type </h3> <h4> 8-32 bits depending on character set and not indexed or sorted </h4> * BYTE : up to 255 bytes * VARBINARY : up to 65K bytes <h4> Usage: small image or sensor signal </h4> <h3> Binary Large Object(BLOB) </h3> <h4> No translation, index, or character set </h4> * TINYBLOB : up to 255 bytes * BLOB : up to 65K * MEDIUMBLOB : up to 16M * LONGBLOB : up to 4G <h4> Usage: Large raw data, files, images, word doc, PDFs, movies </h4> <h3> Interger </h3> <h4> little storage, easy to compare, sort , indexed </h4> * TINYINT : (-128, +128) * SMALLINT : (-32768, +32768) * INT : (2 Billion) * BIGINT : (10**18 ish) <h4> Usage: small image or sensor signal </h4> <h3> Float </h3> <h4> Wide range of values but limmilted accuracy </h4> * FLOAT(32-bit) : 10**38 with 7 digits accuracy * DOUBLE(64-bit) : 10**308 with 14 digits accuracy <h4> Usage: Scientific data </h4> <h3> Dates </h3> <h4> Represent time with integer </h4> * TIMESTAMP : 'YYYY-MM-DD HH:MM:SS'(1970, 2037) * DATETIME : 'YYYY-MM-DD HH:MM:SS' * DATE : 'YYYY-MM-DD' * TIME: 'HH:MM:SS' <h4> Buit-in MySQL function NOW() </h4> --- <h2> 關聯式資料集 </h2> <h3> 1. 構思資料庫關係圖 </h3> >1. Find the core of the database >2. Use the core to create the first table >3. Put non-duplicate columns into the first table >4. Find relation between other columns and point to more table <h3> 2. 標準資料型態 </h3> >* Do not replicate data, use point >* Use integers for keys >* Add special 'key' column to each table, for reference (By AUTO_INCREMENT) <h3> 3. 創建關聯式資料集 </h3> :::spoiler ```sql= CREATE DATABASE Music DEFAULT CHARACTER SET utf8; USE Music; (Command line only) CREATE TABLE Artist ( artist_id INTEGER NOT NULL AUTO_INCREMENT, name VARCHAR(255), PRIMARY KEY(artist_id) ) ENGINE = InnoDB; CREATE TABLE Album ( album_id INTEGER NOT NULL AUTO_INCREMENT, title VARCHAR(255), artist_id INTEGER, PRIMARY KEY(album_id), INDEX USING BTREE (title), CONSTRAINT FOREIGN KEY (artist_id) REFERENCES Artist (artist_id) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE = InnoDB; CREATE TABLE Genre ( genre_id INTEGER NOT NULL AUTO_INCREMENT, name VARCHAR(255), PRIMARY KEY(genre_id) ) ENGINE = InnoDB; CREATE TABLE Track ( track_id INTEGER NOT NULL AUTO_INCREMENT, title VARCHAR(255), len INTEGER, rating INTEGER, count INTEGER, album_id INTEGER, genre_id INTEGER, PRIMARY KEY(track_id), INDEX USING BTREE (title), CONSTRAINT FOREIGN KEY (album_id) REFERENCES Album (album_id) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT FOREIGN KEY (genre_id) REFERENCES Genre (genre_id) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE = InnoDB; INSERT INTO Artist (name) VALUES ('Led Zepplin'); INSERT INTO Artist (name) VALUES ('AC/DC'); INSERT INTO Genre (name) VALUES ('Rock'); INSERT INTO Genre (name) VALUES ('Metal'); INSERT INTO Album (title, artist_id) VALUES ('Who Made Who', 2); INSERT INTO Album (title, artist_id) VALUES ('IV', 1); INSERT INTO Track (title, rating, len, count, album_id, genre_id) VALUES ('Black Dog', 5, 297, 0, 2, 1); INSERT INTO Track (title, rating, len, count, album_id, genre_id) VALUES ('Stairway', 5, 482, 0, 2, 1); INSERT INTO Track (title, rating, len, count, album_id, genre_id) VALUES ('About to Rock', 5, 313, 0, 1, 2); INSERT INTO Track (title, rating, len, count, album_id, genre_id) VALUES ('Who Made Who', 5, 207, 0, 1, 2); ``` ::: <h3> 4. 創建臨時表格 </h3> * Merge multilple databases and list all combinations ```sql Database1 JOIN Database2 JOIN ... ``` * Filter to prevent JOIN from output all the combinations ```sql ON "Foreign key of Database1" = "Foreign key of database2" ``` * Automatically delete date while related data was updated ```sql ON DELETE CASCADE ``` <h3> 5. 多對多關聯式資料集 </h3> <h3> Types of keys </h3> * Primary key : Generally an integer AUTO_INCREMENT field * Logical key : Generally a string for UI application to search (do not use logical key as primary key!!!) * Foreign key : Generally an integer pointing to another table <h2> 條件判斷式差別 </h2> <h3> 資料處理順序 </h3> <h4> 掃描資料集關聯 => 創建臨時表 => 進行計算 => 輸出 </h4> <h3> 1. ON </h3> <h4> 過濾關聯式資料集後創建臨時表 </h4> <h3> 2. WHERE </h3> <h4> 創建所有關聯式資料集臨時表後過濾資料 </h4> <h3> 3. HAVING </h3> <h4> 創建所有關聯式資料集臨時表並進行完統計後再輸出前過濾 </h4> <h3> 運行效率 </h3> <h4> 處理資料數量由上至下遞減,也因此處理速度由上至下減慢 </h4> <h2> 踩雷筆記 </h2> <h3> GROUP BY 錯誤 </h3> <h4> 使用資料庫 </h4> :::spoiler ```sql= CREATE DATABASE Music DEFAULT CHARACTER SET utf8; USE Music; (Command line only) CREATE TABLE Artist ( artist_id INTEGER NOT NULL AUTO_INCREMENT, name VARCHAR(255), PRIMARY KEY(artist_id) ) ENGINE = InnoDB; CREATE TABLE Album ( album_id INTEGER NOT NULL AUTO_INCREMENT, title VARCHAR(255), artist_id INTEGER, PRIMARY KEY(album_id), INDEX USING BTREE (title), CONSTRAINT FOREIGN KEY (artist_id) REFERENCES Artist (artist_id) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE = InnoDB; CREATE TABLE Genre ( genre_id INTEGER NOT NULL AUTO_INCREMENT, name VARCHAR(255), PRIMARY KEY(genre_id) ) ENGINE = InnoDB; CREATE TABLE Track ( track_id INTEGER NOT NULL AUTO_INCREMENT, title VARCHAR(255), len INTEGER, rating INTEGER, count INTEGER, album_id INTEGER, genre_id INTEGER, PRIMARY KEY(track_id), INDEX USING BTREE (title), CONSTRAINT FOREIGN KEY (album_id) REFERENCES Album (album_id) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT FOREIGN KEY (genre_id) REFERENCES Genre (genre_id) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE = InnoDB; INSERT INTO Artist (name) VALUES ('Led Zepplin'); INSERT INTO Artist (name) VALUES ('AC/DC'); INSERT INTO Genre (name) VALUES ('Rock'); INSERT INTO Genre (name) VALUES ('Metal'); INSERT INTO Album (title, artist_id) VALUES ('Who Made Who', 2); INSERT INTO Album (title, artist_id) VALUES ('IV', 1); INSERT INTO Track (title, rating, len, count, album_id, genre_id) VALUES ('Black Dog', 5, 297, 0, 2, 1); INSERT INTO Track (title, rating, len, count, album_id, genre_id) VALUES ('Stairway', 5, 482, 0, 2, 1); INSERT INTO Track (title, rating, len, count, album_id, genre_id) VALUES ('About to Rock', 5, 313, 0, 1, 2); INSERT INTO Track (title, rating, len, count, album_id, genre_id) VALUES ('Who Made Who', 5, 207, 0, 1, 2); ``` ::: <h4> 操作 </h4> ```sql SELECT DISTINCT (Genre.name), Artist.name FROM Track JOIN Album JOIN Artist JOIN Genre WHERE Track.album_id = Album.album_id AND Track.genre_id = Genre.genre_id and Artist.artist_id = Album.artist_id GROUP BY Artist.name; ``` <h4> 報錯 </h4> ```sql ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'music.Genre.name' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by ``` <h4> 解決 </h4> Terminal ```bash sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf ``` 最後一行加上 ```bash sql_mode = "" ``` --- ###### tags: `CS` `MySQL` `SQL` {%hackmd BJrTq20hE %}