1. SQL語言包括哪些型別?
資料定義:Create Table,Alter Table,Drop Table, Craete/Drop Index
資料操縱:Select ,insert,update,delete
資料控制:grant,revoke
2. 行內接,外聯接區別?
內連接是保證兩個表中所有的行都要滿足連接條件,而外連接則不然,
在外連接中,某些不滿條件的列也會顯示出來,也就是說,只限制其中一個表的行,而不限制另一個表的行,分左連接、右連接、全連接三種,
等連接(內連接)、非等連接、自連接、外連接(左、右、全)
Or hash join/merge join/nest loop(cluster join)/index join
1)內連接:只連接匹配的行
select A.c1,B.c2 from A join B on A.c3 = B.c3;
2)左外連接:包含左邊表的全部行(不管右邊的表中是否存在與它們匹配的行)以及右邊表中全部匹配的行
select A.c1,B.c2 from A left join B on A.c3 = B.c3;
3)右外連接:包含右邊表的全部行(不管左邊的表中是否存在與它們匹配的行)以及左邊表中全部匹配的行
select A.c1,B.c2 from A right join B on A.c3 = B.c3;
4)全外連接:包含左、右兩個表的全部行,不管在另一邊的表中是否存在與它們匹配的行
select A.c1,B.c2 from A full join B on A.c3 = B.c3;
5)(theta)連接:使用等值以外的條件來匹配左、右兩個表中的行
select A.c1,B.c2 from A join B on A.c3 != B.c3;
6)交叉連接:生成笛卡爾積——它不使用任何匹配或者選取條件,而是直接將一個資料源中的每個行與另一個資料源的每個行一一匹配
select A.c1,B.c2 from A,B;
3. 什么是存盤程序?用什么來呼叫?
存盤程序是一個預編譯的SQL陳述句, 簡單的說存盤程序是為了完成某個資料庫中的特定功能而撰寫的陳述句集,該陳述句集包括SQL陳述句(對資料的增刪改查)、條件陳述句和回圈陳述句等,優點是允許模塊化的設計,就是說只需創建一次,以后在該程式中就可以呼叫多次,如果某次操作需要執行多次SQL,使用存盤程序比單純SQL陳述句執行要快,可以用一個命令物件來呼叫存盤程序(CALL),
4.觸發器的作用?
觸發器是一中特殊的存盤程序,主要是通過事件來觸發而被執行的,它可以強化約束,來維護資料的完整性和一致性,可以跟蹤資料庫內的操作從而不允許未經許可的更新和變化,可以聯級運算,如,某表上的觸發器上包含對另一個表的資料操作,而該操作又會導致該表觸發器被觸發,
5. 索引的作用?和它的優點缺點是什么?
索引就一種特殊的查詢表,資料庫的搜索引擎可以利用它加速對資料的檢索,它很類似與現實生活中書的目錄,不需要查詢整本書內容就可以找到想要的資料,索引可以是唯一的,創建索引允許指定單個列或者是多個列,缺點是它減慢了資料錄入的速度,同時也增加了資料庫的尺寸大小,
6. 什么是記憶體泄漏?
一般我們所說的記憶體泄漏指的是堆記憶體的泄漏,堆記憶體是程式從堆中為其分配的,大小任意的,使用完后要顯示釋放記憶體,當應用程式用關鍵字new等創建物件時,就從堆中為它分配一塊記憶體,使用完后程式呼叫free或者delete釋放該記憶體,否則就說該記憶體就不能被使用,我們就說該記憶體被泄漏了,
7. 如何維護資料庫的完整性和一致性?
盡可能使用約束,如check,主鍵,外鍵,非空欄位等來約束,這樣做效率最高,也最方便,其次是使用觸發器,這種方法可以保證,無論什么業務系統訪問資料庫都可以保證資料的完整新和一致性,最后考慮的是自寫業務邏輯,但這樣做麻煩,編程復雜,效率低下,
8. 什么是事務?什么是鎖?
事務就是被系結在一起作為一個邏輯作業單元的SQL陳述句分組,如果任何一個陳述句操作失敗那么整個操作就被失敗,以后操作就會回滾到操作前狀態,或者是上有個節點,為了確保要么執行,要么不執行,就可以使用事務,要將一組陳述句作為事務考慮,就需要通過ACID測驗,即原子性,一致性,隔離性和持久性,
鎖:在所有的DBMS中,鎖是實作事務的關鍵,鎖可以保證事務的完整性和并發性,與現實生活中鎖一樣,它可以使某些資料的擁有者,在某段時間內不能使用某些資料或資料結構,當然鎖還分級別的,共享鎖(只讀不寫)、排他鎖(可讀可寫)
9. 事務的隔離級別有哪些?
事務隔離級別包括: 原子性,即不可分割性,事務要么全部被執行,要么就全部不被執行; 一致性或可串性,事務的執行使得資料庫從一種正確狀態轉換成另一種正確狀態; 隔離性,在事務正確提交之前,不允許把該事務對資料的任何改變提供給任何其他事務; 持久性,事務正確提交后,其結果將永久保存在資料庫中,即使在事務提交后有了其他故障,事務的處理結果也會得到保存,
10. 什么叫視圖?游標是什么?
視圖是一種虛擬的表,具有和物理表相同的功能,可以對視圖進行增,改,查,操作,試圖通常是有一個表或者多個表的行或列的子集,對視圖的修改不影響基本表,它使得我們獲取資料更容易,相比多表查詢,
游標:是對查詢出來的結果集作為一個單元來有效的處理,游標可以定在該單元中的特定行,從結果集的當前行檢索一行或多行,可以對結果集當前行做修改,一般不使用游標,但是需要逐條處理資料的時候,游標顯得十分重要,游標用于定位結果集的行,通過判斷全域變數@@FETCH_STATUS可以判斷是否到了最后,通常此變數不等于0表示出錯或到了最后,
11. 什么是主鍵?什么是外鍵?
主鍵是表格里的(一個或多個)欄位,只用來定義表格里的行;主鍵里的值總是唯一的,外鍵是一個用來建立兩個表格之間關系的約束,這種關系一般都涉及一個表格里的主鍵欄位與另外一個表格(盡管可能是同一個表格)里的一系列相連的欄位,那么這些相連的欄位就是外鍵,
主鍵在本表中是唯一的、不可為空的,外鍵可以重復可以唯空;外鍵和另一張表的主鍵關聯,不能創建對應表中不存在的外鍵,
12. 對一個投入使用的在線事務處理表格有過多索引需要有什么樣的性能考慮?
對一個表格的索引越多,資料庫引擎用來更新、插入或者洗掉資料所需要的時間就越多,因為在資料操控發生的時候索引也必須要維護,
13、可以用什么來確保表格里的欄位只接受特定范圍里的值?
Check限制,它在資料庫表格里被定義,用來限制輸入該列的值, 觸發器也可以被用來限制資料庫表格里的欄位能夠接受的值,但是這種辦法要求觸發器在表格里被定義,這可能會在某些情況下影響到性能,因此,微軟建議使用Check限制而不是其他的方式來限制域的完整性,
14. 什么是相關子查詢?如何使用這些查詢?
經驗更加豐富的開發人員將能夠準確地描述這種型別的查詢, 相關子查詢是一種包含子查詢的特殊型別的查詢,查詢里包含的子查詢會真正請求外部查詢的值,從而形成一個類似于回圈的狀況,
15. 使用索引查詢一定能提高查詢的性能嗎?為什么?
通常,通過索引查詢資料比全表掃描要快.但是我們也必須注意到它的代價. 索引需要空間來存盤,也需要定期維護, 每當有記錄在表中增級訓索引列被修改時,索引本身也會被修改. 這意味著每條記錄的INSERT,DELETE,UPDATE將為此多付出4,5 次的磁盤I/O. 因為索引需要額外的存盤空間和處理,那些不必要的索引反而會使查詢反應時間變慢.使用索引查詢不一定能提高查詢性能,索引范圍查詢(INDEX RANGE SCAN)適用于兩種情況: 基于一個范圍的檢索,一般查詢回傳結果集小于表中記錄數的30%宜采用; 基于非唯一性索引的檢索 索引就是為了提高查詢性能而存在的,如果在查詢中索引沒有提高性能,只能說是用錯了索引,或者講是場合不同
16. 查詢A(ID,Name)表中第31至40條記錄,ID作為主鍵可能是不連續增長的列, 查詢陳述句?
select top 10 * from A where ID >(select max(ID) from (select top 30 ID from A order by ID ) T) order by ID
17. 分頁查詢陳述句?
(1)mysql的分頁查詢
select o.* from (sql) o limit firstIndex,pageSize
(2)sqlserver2005的分頁查詢
select top pageSize o.* from (select row_number() over(order by orderColumn) as rownumber,*from(sql) as o where rownumber>firstIndex;
(3)oracle分頁查詢
select * from(select a.*,ROWNUM rn from(sql) a where ROWNUM<=(firstIndex+pageSize)) wherern>firstIndex
18. 如何優化資料庫,如何提高資料庫的性能?
1)給資料庫做索引,合理的索引能立即顯著地提高資料庫整個系統的性能,
2)在適當的情況下,盡可能的用存盤程序而不是SQL查詢,因為前者已經過了預編譯,運行速度更快,
3)優化查詢陳述句,通過高性能的查詢陳述句提高資料庫的性能,
19、說出一些資料庫優化方面的經驗?
用PreparedStatement 一般來說比Statement性能高,
有外鍵約束會影響插入和洗掉性能,如果程式能夠保證資料的完整性,那在設計資料庫時就去掉外鍵,
根據掃描的原理,第一條子查詢陳述句要比第二條關聯查詢的效率高:
1)select e.name,e.salary where e.managerid=(select id from employee where name='zxx'); 2)select e.name,e.salary,m.name,m.salary from employees e,employees m where e.managerid = m.id and m.name='zxx';
表中允許適當冗余,如,主題帖的回復數量和最后回復時間等
將姓名和密碼單獨從用戶表中獨立出來,這可以是非常好的一對一的案例,
sql陳述句全部大寫,特別是列名和表名都大寫,特別是sql命令的快取功能,更加需要統一大小寫,sql陳述句?發給oracle服務器?語法檢查和編譯成為內部指令?快取和執行指令,根據快取的特點,不要拼湊條件,而是用?和PreparedStatment
還有索引對查詢性能的改進也是值得關注的,
20. 表與表之間的關聯關系
分為3種:一對一、一對多、多對多,
21. 事前觸發和事后觸發有何區別?陳述句級觸發和行級觸發有何區別?
事前觸發器運行于觸發事件發生之前,而事后觸發器運行于觸發事件發生之后,通常事前觸發器可以獲取事件之前和新的欄位值,陳述句級觸發器可以在陳述句執行前或后執行,而行級觸發在觸發器所影響的每一行觸發一次,
22. 資料庫設計的必要性及設計步驟
好的資料庫結構有利于:節省資料的存盤空間,能夠保證資料的完整性,方便進行資料庫應用系統的開發
設計不好的資料庫結構將導致:資料冗余、存盤空間浪費和記憶體空間浪費
不管資料庫的大小和復雜程度如何,可以用下列基本步驟來設計資料庫:收集資訊--標識物件--設計資料模型--標識每個物件--存盤的資訊型別–標識物件之間的關系
23. 什么是資料模型?什么是規范化?
資料模型是一種標識物體型別及其物體間聯系的模型,典型的資料模型有網狀模型、層次模型和關系模型,
從關系資料庫的表中,除去冗余資料的程序稱為規范化,包括:精簡資料庫的結構,從表中洗掉冗余的列,標識所有依賴于其它資料的資料
24. 談談資料庫設計的三范式
第一范式的定義:如果一個表中沒有重復組(即行與列的交叉點上只有一個值,而不是一組值),則這個表屬于第一范式(常記成1NF),簡而言之:"每一欄位只存盤一個值",例如:職工號,姓名,電話號碼組成一個表(一個人可能有一個辦公室電話 和一個家里電話號碼)
第二范式的定義:如果一個表屬于1NF,任何屬性只依賴于關鍵字,則這個表屬于第二范式(常記成2NF ),簡而言之:必須先符合1NF的條件,且每一行都能被唯一的識別,將1NF轉換成2NF的方法是添加主鍵,例如:學號,姓名,課程名,成績
第三范式的定義:如果一個表屬于2NF,且不包含傳遞依賴性,則這個表是第三范式(常記成 3NF),滿足3NF的表中不包含傳遞依賴,簡而言之:沒有一個非關鍵屬性依賴于另一個非關鍵屬性,例如:表一:學號,課程號,成績, 表二:學號,姓名,所在系,系名稱,系地址,表三:課程號,課程名,學分
25. union和union all有什么不同?
Union和Union All的區別之一在于對重復結果的處理, UNION在進行表鏈接后會篩選掉重復的記錄,所以在表鏈接后會對所產生的結果集進行排序運算,洗掉重復的記錄再回傳結果,實際大部分應用中是不會產生重復的記錄,最常見的是程序表與歷史表UNION,如: select * from gc_dfys union select * from ls_jg_dfys 這個SQL在運行時先取出兩個表的結果,再用排序空間進行排序洗掉重復的記錄,最后回傳結果集,如果表資料量大的話可能會導致用磁盤進行排序, 而UNION ALL只是簡單的將兩個結果合并后就回傳,這樣,如果回傳的兩個結果集中有重復的資料,那么回傳的結果集就會包含重復的資料了, 從效率上說,UNION ALL 要比UNION快很多,所以,如果可以確認合并的兩個結果集中不包含重復的資料的話,那么就使用UNION ALL
26. 設計資料庫應注意那些問題?
(1)原始單據與物體之間的關系
可以是一對一、一對多、多對多的關系,在一般情況下,它們是一對一的關系:即一張原始單據對應且只對應一個物體,在特殊情況下,它們可能是一對多或多對一的關系,即一張原始單證對應多個物體,或多張原始單證對應一個物體,這里的物體可以理解為基本表,明確這種對應關系后,對我們設計錄入界面大有好處,
〖例1〗:一份員工履歷資料,在人力資源資訊系統中,就對應三個基本表:員工基本情況表、社會關系表、作業簡歷表,這就是“一張原始單證對應多個物體”的典型例子,
(2)主鍵與外鍵
一般而言,一個物體不能既無主鍵又無外鍵,在E—R 圖中, 處于葉子部位的物體, 可以定義主鍵,也可以不定義主鍵(因為它無子孫), 但必須要有外鍵(因為它有父親),主鍵與外鍵的設計,在全域資料庫的設計中,占有重要地位,當全域資料庫的設計完成以后,有個美國資料庫設計專家說:“鍵,到處都是鍵,除了鍵之外,什么也沒有”,這就是他的資料庫設計經驗之談,也反映了他對資訊系統核心(資料模型)的高度抽象思想,因為:主鍵是物體的高度抽象,主鍵與
外鍵的配對,表示物體之間的連接,
(3)基本表的性質
基本表與中間表、臨時表不同,因為它具有如下四個特性:
1)原子性,基本表中的欄位是不可再分解的,
2)原始性,基本表中的記錄是原始資料(基礎資料)的記錄,
3)演繹性,由基本表與代碼表中的資料,可以派生出所有的輸出資料,
4)穩定性,基本表的結構是相對穩定的,表中的記錄是要長期保存的,
理解基本表的性質后,在設計資料庫時,就能將基本表與中間表、臨時表區分開來,
(4)范式標準
基本表及其欄位之間的關系, 應盡量滿足第三范式,但是,滿足第三范式的資料庫設計,往往不是最好的設計,為了提高資料庫的運行效率,常常需要降低范式標準:適當增加冗余,達到以空間換時間的目的,
〖例2〗:有一張存放商品的基本表,如表1所示,“金額”這個欄位的存在,表明該表的設計不滿足第三范式,因為“金額”可以由“單價”乘以“數量”得到,說明“金額”是冗余欄位,但是,增加“金額”這個冗余欄位,可以提高查詢統計的速度,這就是以空間換時間的作法,
在Rose 2002中,規定列有兩種型別:資料列和計算列,“金額”這樣的列被稱為“計算列”,而“單價”和“數量”這樣的列被稱為“資料列”,
表1 商品表的表結構
商品名稱 商品型號 單價 數量 金額
電視機 29吋 2,500 40 100,000
(5)通俗地理解三個范式
通俗地理解三個范式,對于資料庫設計大有好處,在資料庫設計中,為了更好地應用三個范式,就必須通俗地理解三個范式(通俗地理解是夠用的理解,并不是最科學最準確的理解):
第一范式:1NF是對屬性的原子性約束,要求屬性具有原子性,不可再分解;
第二范式:2NF是對記錄的惟一性約束,要求記錄有惟一標識,即物體的惟一性;
第三范式:3NF是對欄位冗余性的約束,即任何欄位不能由其他欄位派生出來,它要求欄位沒有冗余,
沒有冗余的資料庫設計可以做到,但是,沒有冗余的資料庫未必是最好的資料庫,有時為了提高運
行效率,就必須降低范式標準,適當保留冗余資料,具體做法是:在概念資料模型設計時遵守第三范式
,降低范式標準的作業放到物理資料模型設計時考慮,降低范式就是增加欄位,允許冗余,
(6)要善于識別與正確處理多對多的關系
若兩個物體之間存在多對多的關系,則應消除這種關系,消除的辦法是,在兩者之間增加第三個物體,這樣,原來一個多對多的關系,現在變為兩個一對多的關系,要將原來兩個物體的屬性合理地分配到三個物體中去,這里的第三個物體,實質上是一個較復雜的關系,它對應一張基本表,一般來講,資料庫設計工具不能識別多對多的關系,但能處理多對多的關系,
〖例3〗:在“圖書館資訊系統”中,“圖書”是一個物體,“讀者”也是一個物體,這兩個物體之間的關系,是一個典型的多對多關系:一本圖書在不同時間可以被多個讀者借閱,一個讀者又可以借多本圖書,為此,要在二者之間增加第三個物體,該物體取名為“借還書”,它的屬性為:借還時間、借還標志(0表示借書,1表示還書),另外,它還應該有兩個外鍵(“圖書”的主鍵,“讀者”的主鍵),使它能與“圖書”和“讀者”連接,
(7)主鍵PK的取值方法
PK是供程式員使用的表間連接工具,可以是一無物理意義的數字串, 由程式自動加1來實作,也可以是有物理意義的欄位名或欄位名的組合,不過前者比后者好,當PK是欄位名的組合時,建議欄位的個數不要太多,多了不但索引占用空間大,而且速度也慢,
(8)正確認識資料冗余
主鍵與外鍵在多表中的重復出現, 不屬于資料冗余,這個概念必須清楚,事實上有許多人還不清楚,非鍵欄位的重復出現, 才是資料冗余!而且是一種低級冗余,即重復性的冗余,高級冗余不是欄位的重復出現,而是欄位的派生出現,
〖例4〗:商品中的“單價、數量、金額”三個欄位,“金額”就是由“單價”乘以“數量”派生出來的,它就是冗余,而且是一種高級冗余,冗余的目的是為了提高處理速度,只有低級冗余才會增加資料的不一致性,因為同一資料,可能從不同時間、地點、角色上多次錄入,因此,我們提倡高級冗余(派生性冗余),反對低級冗余(重復性冗余),
(9)E--R圖沒有標準答案
資訊系統的E--R圖沒有標準答案,因為它的設計與畫法不是惟一的,只要它覆寫了系統需求的業務范圍和功能內容,就是可行的,反之要修改E--R圖,盡管它沒有惟一的標準答案,并不意味著可以隨意設計,好的E—R圖的標準是:結構清晰、關聯簡潔、物體個數適中、屬性分配合理、沒有低級冗余,
(10) 視圖技術在資料庫設計中很有用
與基本表、代碼表、中間表不同,視圖是一種虛表,它依賴資料源的實表而存在,視圖是供程式員使用資料庫的一個視窗,是基表資料綜合的一種形式, 是資料處理的一種方法,是用戶資料保密的一種手段,為了進行復雜處理、提高運算速度和節省存盤空間, 視圖的定義深度一般不得超過三層, 若三層視圖仍不夠用, 則應在視圖上定義臨時表, 在臨時表上再定義視圖,這樣反復交迭定義, 視圖的深度就不受限制了,
對于某些與國家政治、經濟、技術、軍事和安全利益有關的資訊系統,視圖的作用更加重要,這些系統的基本表完成物理設計之后,立即在基本表上建立第一層視圖,這層視圖的個數和結構,與基本表的個數和結構是完全相同,并且規定,所有的程式員,一律只準在視圖上操作,只有資料庫管理員,帶著多個人員共同掌握的“安全鑰匙”,才能直接在基本表上操作,請讀者想想:這是為什么?
(11)中間表、報表和臨時表
中間表是存放統計資料的表,它是為資料倉庫、輸出報表或查詢結果而設計的,有時它沒有主鍵與外鍵(資料倉庫除外),臨時表是程式員個人設計的,存放臨時記錄,為個人所用,基表和中間表由DBA維護,臨時表由程式員自己用程式自動維護,
(12) 完整性約束表現在三個方面
域的完整性:用Check來實作約束,在資料庫設計工具中,對欄位的取值范圍進行定義時,有一個Check按鈕,通過它定義欄位的值城,
參照完整性:用PK、FK、表級觸發器來實作,
用戶定義完整性:它是一些業務規則,用存盤程序和觸發器來實作,
(13) 防止資料庫設計打補丁的方法是“三少原則”
1) 一個資料庫中表的個數越少越好,只有表的個數少了,才能說明系統的E--R圖少而精,去掉了
重復的多余的物體,形成了對客觀世界的高度抽象,進行了系統的資料集成,防止了打補丁式的設計;
2)一個表中組合主鍵的欄位個數越少越好,因為主鍵的作用,一是建主鍵索引,二是做為子表的
外鍵,所以組合主鍵的欄位個數少了,不僅節省了運行時間,而且節省了索引存盤空間;
3) 一個表中的欄位個數越少越好,只有欄位的個數少了,才能說明在系統中不存在資料重復,且很少有資料冗余,更重要的是督促讀者學會“列變行”,這樣就防止了將子表中的欄位拉入到主表中去,在主表中留下許多空余的欄位,所謂“列變行”,就是將主表中的一部分內容拉出去,另外單獨建一
個子表,這個方法很簡單,有的人就是不習慣、不采納、不執行,
資料庫設計的實用原則是:在資料冗余和處理速度之間找到合適的平衡點,“三少”是一個整體概念,綜合觀點,不能孤立某一個原則,該原則是相對的,不是絕對的,“三多”原則肯定是錯誤的,試想:若覆寫系統同樣的功能,一百個物體(共一千個屬性) 的E--R圖,肯定比二百個物體(共二千個屬性)
的E--R圖,要好得多,
提倡“三少”原則,是叫讀者學會利用資料庫設計技術進行系統的資料集成,資料集成的步驟是將檔案系統集成為應用資料庫,將應用資料庫集成為主題資料庫,將主題資料庫集成為全域綜合資料庫,集成的程度越高,資料共享性就越強,資訊孤島現象就越少,整個企業資訊系統的全域E—R圖中物體的
個數、主鍵的個數、屬性的個數就會越少,
提倡“三少”原則的目的,是防止讀者利用打補丁技術,不斷地對資料庫進行增刪改,使企業資料庫變成了隨意設計資料庫表的“垃圾堆”,或資料庫表的“大雜院”,最后造成資料庫中的基本表、代碼表、中間表、臨時表雜亂無章,不計其數,導致企事業單位的資訊系統無法維護而癱瘓,
“三多”原則任何人都可以做到,該原則是“打補丁方法”設計資料庫的歪理學說,“三少”原則是少而精的原則,它要求有較高的資料庫設計技巧與藝術,不是任何人都能做到的,因為該原則是杜絕用“打補丁方法”設計資料庫的理論依據,
(14) 提高資料庫運行效率的辦法
在給定的系統硬體和系統軟體條件下,提高資料庫系統的運行效率的辦法是:
1)在資料庫物理設計時,降低范式,增加冗余, 少用觸發器, 多用存盤程序,
2) 當計算非常復雜、而且記錄條數非常巨大時(例如一千萬條),復雜計算要先在資料庫外面,以檔案系統方式用C++語言計算處理完成之后,最后才入庫追加到表中去,這是電信計費系統設計的經驗,
3)發現某個表的記錄太多,例如超過一千萬條,則要對該表進行水平分割,水平分割的做法是,以該表主鍵PK的某個值為界線,將該表的記錄水平分割為兩個表,若發現某個表的欄位太多,例如超過八十個,則垂直分割該表,將原來的一個表分解為兩個表,
4)對資料庫管理系統DBMS進行系統優化,即優化各種系統引數,如緩沖區個數,
5) 在使用面向資料的SQL語言進行程式設計時,盡量采取優化演算法,
總之,要提高資料庫的運行效率,必須從資料庫系統級優化、資料庫設計級優化、程式實作級優化,這三個層次上同時下功夫,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/235985.html
標籤:其他
