問:如果你的表沒有定義主鍵,你知道 MySQL 會怎么做嗎 ?
答:Innodb表中在沒有默認主鍵的情況下會生成一個6byte空間的自動增長主鍵
我需要創建一個學校庫,存儲教師、學生、院系等信息,你覺得叫做 school 好嗎 ?為什么 ?
答:個人覺得業務初期可能沒問題。但是學生表后期會膨脹,很有可能獨立成一個庫或者為這個表做備份庫,如果這個學校庫起名叫school,那學生庫或者學生表的備份庫起名字的時候選擇會比較苦難,不大好起一個簡要達意的名字,不知道這么考慮對不對。
問:我編寫的 SQL 語句需要做多表的 join 操作,應該給哪些列建索引呢 ?
答:where子句中的字段
講師回答 / 張勤一
沁塵你好:第一個問題,如果你的表沒有定義主鍵,那么 MySQL 首先判斷表中是否有非空的唯一索引,如果有,則該列即為主鍵;如果不符合上述條件,InnoDB存儲引擎自動創建一個6字節大小的指針。第二個問題,直接命名為 school 并不好,最好是加上一些前綴(比如地域之類的),主要目的是方便未來的擴展,比如加入其它的 school,不會同名。第三個問題,join 操作的話,where 條件和 join 的列最好都加上索引,但是,此時需要考慮索引的個數不要過多(一般一張表的索引個數不超過5個)。
騎著豬找未來
問題一:從文中的信息來看,count(n)或count(*)是走索引的,猜測sum()是因為不走索引導致的 問題二:書寫順序為select、from、where、group by、 order by、having
講師回答 / 張勤一
騎豬你好,確實是這樣的,順序是對的
阿斯拉菲
問題1 case when 經常統計、縱表轉橫表的時候用過,ifnull, if 個人相對用的少 問題2 這個親身體會,mysql 5.x版本默認大小寫不敏感,mysql 8 默認大小寫敏感,修改的話必須是數據庫初始化之前修改,之后更改是無效的
講師回答 / 張勤一
是的,這些判斷語句在部分情況下是比較好用的,但是,如果不這樣寫,其實在代碼中判斷,效率也是非常高的,不一定非要這樣用。關于大小寫敏感的問題,我的個人習慣是精確查找,而不是依賴于數據庫系統的特性。
沁塵
問:將時間轉換為時間戳,并使用 int 或者 bigint 類型去存儲,你覺得這樣可行嗎 ? 答:看正文的時候正好奇為啥沒提到存儲int/bigint時間戳,用int/bigint和datetime存儲在不同項目都使用過,感受就是int/bigint計算上很方便。特別是當前端項目對于時間展示有不同的格式需求的時候,數據庫中存儲的是int/bigint(或者vo層轉換)直接返回給前端,前端可以更方便的定制格式而不用先把datetime轉成時間戳。但是如果沒這方面的需求,那直接存儲datetime就是最方便的,可以減少轉換的次數。所以個人覺得,從存儲角度上來說,如果沒有格式定制的需求,直接存儲datetime最省事。 問:大多數時候,我們會選擇將主鍵設置為 bigint 數據類型,你知道這是為什么嗎 ? 答:不知道
講師回答 / 張勤一
沁塵你好: 第一個問題,是否可以考慮將時間存儲為整型?這是完全可以的,正如你所說,時間是整型的話,前端可以方便的進行轉換,而且不用考慮精度的問題,且這種轉換帶來的性能損耗幾乎是可以忽略不計的。當然,如果僅僅是 java 系統之間使用的話,使用 datetime 存儲是最方便的,序列化和反序列化都只需要一個注解就可以完成。 第二個問題,為什么考慮將主鍵設置為 binint 類型?這里的主要思想就是為了將來的擴展,因為 int 類型的最大表示范圍大約是 20 億,這對于 99% 的項目都基本足夠用了。但是,如果考慮到將來業務發展的比較迅速,就需要使用 bigint 了。如果一開始沒有使用 bigint,而是使用 int,那么,后期的遷移將會是很大的工作量。
街邊七號
1.為什么執行flush logs?猜測可能mysql執行操作后不會立即將操作信息記錄在binlog,而是停留在內存中由mysql服務器在合適的時機進行異步刷盤,執行flush logs來確保最新的數據庫操作可能記錄在binlog中,來防止數據恢復都是 2.不知道
講師回答 / 張勤一
第一個問題說的是對的,先保存在內存中,起到緩沖的作用;第二個問題的話,其實就是指定起始位置和起始時間
沁塵
問:如果你的表沒有定義主鍵,你知道 MySQL 會怎么做嗎 ? 答:Innodb表中在沒有默認主鍵的情況下會生成一個6byte空間的自動增長主鍵 我需要創建一個學校庫,存儲教師、學生、院系等信息,你覺得叫做 school 好嗎 ?為什么 ? 答:個人覺得業務初期可能沒問題。但是學生表后期會膨脹,很有可能獨立成一個庫或者為這個表做備份庫,如果這個學校庫起名叫school,那學生庫或者學生表的備份庫起名字的時候選擇會比較苦難,不大好起一個簡要達意的名字,不知道這么考慮對不對。 問:我編寫的 SQL 語句需要做多表的 join 操作,應該給哪些列建索引呢 ? 答:where子句中的字段
講師回答 / 張勤一
沁塵你好:第一個問題,如果你的表沒有定義主鍵,那么 MySQL 首先判斷表中是否有非空的唯一索引,如果有,則該列即為主鍵;如果不符合上述條件,InnoDB存儲引擎自動創建一個6字節大小的指針。第二個問題,直接命名為 school 并不好,最好是加上一些前綴(比如地域之類的),主要目的是方便未來的擴展,比如加入其它的 school,不會同名。第三個問題,join 操作的話,where 條件和 join 的列最好都加上索引,但是,此時需要考慮索引的個數不要過多(一般一張表的索引個數不超過5個)。
街邊七號
1. 用mybatis動態sql作批量錄入 2. 可以考慮, 但此時sql耗時應基本集中在數據錄入和更新索引的操作上, 性能受限于磁盤的因素應該比較大, 上多線程不如換ssd. 3. 單條錄入需要mysql服務器每次都檢查語法編譯sql語句耗時較長, 批量和Load data可以省去很多這些事件, 但同樣的批量錄入這種形式增大了單條sql的大小及設置的package參數。此時單條sql從客戶端發送到mysql服務器的時候會比較長,占用帶寬。
街邊七號
1. a.自增主鍵. b.盡量保證字段小一些. c.適當的冗余存儲. d. 盡量讓列值非空. 2. where子句字段類型和操作值的類型不一致如varchar類型的列`year`判斷時使用where year = '2020'; like模糊前綴匹配; 對于聚簇索引條件丟失前綴匹配; where中使用SQL函數; 查詢不使用索引列. 3.
街邊七號
1. 環形哈??臻g,添加節點后很多數據不需要移動。 2. 垂直拆分實現簡單,而且水平拆分可能會導致where查詢實現困難。 3. id決定了數據記錄存放的庫和表,可以定位到數據的存放位置。 4. 使用定時任務做同步,但是業務中直接查詢結果由于定時任務可能延時可能變得不可信,需要自行校驗 5.沒想到什么好辦法,就是自己維護一個userid和這些信息數據映射關系,并以此來找到userId再進行查詢
無心鐵憨憨
一哥,有個問題沒想明白,在事物隔離級別為可重復讀的情況下,事物A第一次讀取的數據為1800,然后事物B修改為2000,事物A再次讀取還是1800,因為事物B沒有進行提交,但是當事物B提交之后再讀取還是1800,那2000去哪里了,是否要等事物A執行完畢之后,再次查詢,才會讀到最新的2000?還是說需要在一個新的會話中才能讀取到最新的數據?
講師回答 / 沁塵
不管事務B提交了沒有,事務A讀到的都是這條記錄的快照(1800時的狀態),2000在事務B提交后就寫到新的快照副本去了,這時候另一個事務如果查詢,那就是看到2000這個狀態的快照副本了。
想好名字再改
老師,假設我要查詢每個用戶能夠接受的最大的預算的廣告信息該怎么寫 我目前的寫法 SELECT user_id,MAX(budget) FROM ad_unit WHERE unit_status = 0 GROUP BY user_id 我還想看到這條廣告的詳細信息
講師回答 / 張勤一
最好的做法不是寫一條 SQL 語句,而是在代碼中經過兩次查詢,再去拼接對應的信息