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