開源社區8月問答合集:想用 MongoDB 取代 MySQL 可以嗎?

開源社區8月問答合集:想用 MongoDB 取代 MySQL 可以嗎?

關注開源中國OSC頭條號,獲取最新技術資訊


開源中國問答區新欄目“OSCHINA 問答合集”上線啦,本期收錄了 8 月高熱度的問題及回覆(吐槽),希望能讓你有所收穫~!

進入問答區:

你可以在技術問答版塊暢聊技術

你可以在職業生涯版塊尋道解惑

你可以在IT大雜燴版塊和大家談笑風生

我們希望:

這裡可以成為一個能讓大家有所收穫的地方。因此,這裡拒絕攻擊、拒絕謾罵、拒絕無腦黑。

這裡可以沉澱大家各種的技術問題。無論是新手的基礎問題,還是資深開發的深度問題,都是有價值的。

這是一個更純粹討論技術的地方,能給程序員提供一片友好交流的清淨之地,不懂的可以在這裡尋找幫助,懂的可以在這裡幫助別人。

總之,

在這裡你可以向所有人提問。

反正你的問題可能會沒答案。;-)

這期的技術問答內容相當豐富且詳實,代碼、配圖該有的都有了,絕對是高質量的問答,廢話不說,各位繼續閱讀吧!

==========分割線==========

開源中國技術問答

@雙人魚XKQ:酒店預訂,飛機票預定的時候,每個日期對應一個價格,是如何實現的?

問題:預定酒店的時候,選擇預定的時間,有的會直接在時間下方標明該日期房間的價格,不同的日期對應不同的價格。具體這個業務邏輯如何實現?

方案1:設置365天的每一天的價格(太累)

方案2:在獲取時間的時候,根據價格規則進行獲取,比如說我平時的價格設置為100,國慶節的價格設置為500,在獲取價格的時候,根據價格規則中設置的進行獲取。

現在能想到的方法就是這些了,也是請教別人獲取到的方案,希望有做這方面的朋友多多指點。

>>>wxk_java

當初做過酒店預訂的項目說下,方案也就是樓上所說的方案一:

房源價格設定默認價格,如需特殊價格後臺設定開始-結束日期價格放到一張新表然後遍歷,做好狀態碼 房源可能有鎖定等等狀態。

也不覺得比較麻煩

>>>lgwait

一般來說採用方案一,酒店方面有個名詞叫日曆房,每天的價格設置靈活,想改哪天就改哪天,光有價格還不行,還要有剩餘房間數量,機票數據,一般是通過接口獲取,做緩存,每時每刻艙位剩餘座位都會變化的

>>>tinyhare

我覺得看需求方的要求,需求方要求設個默認價格,下單提前M天是N的優惠不就自動算了,再給配置手工指定價格。如果需求方就要指定每天的價格,那就提供個快速配置的方案,選中時間範圍批量設置價格。我覺得完全看定價策略:邏輯生成的就做好邏輯,手工指定的就做好方便操作

>>>氪金

方案1,但你可以提供設價工具,比如可以直接設一年的標準價,然後把特價時段拿出來單獨設價,以特價為最高優先價格

>>>木有文化

並不是方案一,舉個例子,9.1號買10.1號的和10.1號買10.1號的,價格完全不一樣,

可以參考航空的運價系統,,

>>>魔力貓

方案1不累,沒人規定你必須天天寫。這個只是數據庫記錄的結果。而結果的處理過程只需要你填寫一個時間區間,然後寫上價格。系統循環插就是了。

@踏破鐵鞋無覓處:慢 sql 和多次 sql 查詢那個好?

今天為了實現一個功能,光sql語句寫了五六十行,每次修改sql的時候,也會想半天,感覺sql寫的很複雜。

那麼對於複雜的功能,多次查詢後整合好,還是一個sql查詢出來好呢?(查詢結果是多條數據)

>>>飄搖清風

似乎不同的行業不同的應用要求不一樣吧?我做的應用是超大數據量,但一插入變化就不大的,一般是拆成多條sql查詢出來拼裝。因為數據變化不大,數據一致性問題比較小,也不會因為數據量太大而長時間鎖表。如果你的應用對數據一致性要求很高如財務、網上商城的庫存之類的,感覺還是一條sql搞定好點,不然查詢了一部分後,前面查詢的數據又變了,數據就不太一致了。

PS:我因為一條大sql查詢把服務搞死過。。。

>>>sxgkwei

飄搖清風 說的業務場景非常有道理,所以你得先考慮業務場景是否有強一致性要求。其次,大多數情況下,我覺得一個一個查出來整合會效率更高。原因如下:

1.你能問這個問題,一般認為就是頁面展示查詢。那麼為了完成整體目標而分次查詢,總次數也不會太多。

2.分次查詢,有利於數據庫自動使用到索引,會提高查詢效率

3.一般單表查詢,對於業務系統和 orm 框架來說,很多是有緩存的,其實查的是緩存,效率更高,而多表聯合查詢,一般會禁用這個級別的緩存(因為緩存了可能因為其它位置修改其中一個表的數據而導致緩存更新不了,導致查詢出錯誤數據),就會導致聯合查詢更慢。

4.聯合查詢的sql語句,大多數在查詢語法過程中,總數據處理量會變成多表的乘積。總處理數據量是 n*m*...,那麼根本就快不起來。而單表查幾條,參與運算的數據量就是主數據加幾條關聯數據。

綜上,在大多數情況下,實際上關聯的複雜 sql 查詢,在整體應用層面,會是個差勁的選擇。

>>>melon_jj

如果數據量小的話基本沒有區別。

一次查詢的優點是隻需要一次連接,數據庫查詢的時候,連接是個耗時的操作。缺點是如果兩個表數據多,則中間結果集太大,需要較多的內存資源。

多次查詢的優缺點和一次查詢正好反過來。另外多次查詢也可以在程序中對每一次查詢的中間結果做處理,這是一個靈活性。如果數據量大的話,多次查詢要快一些,相當於是用空間換時間,如你上述所說,拼裝sql會比較麻煩,但帶來的是效率的提升,我認為還是值得的。如果表中建立了大量的索引的話,索引的命中率也很高。效率也會大幅提升。

>>>藍水晶飛機: 補充一下:

1.其實平常有連接池複用,不會有太多明顯的多次連接開銷;

2.在我做的系統裡面,背慢鍋的都是JOIN

3.其實在ORM框架來看,JOIN產生了中間結果,竟不是A也不是B而是AB混合體,因此緩存怎麼搞(不用緩存了)所以問題3還是各查個的吧然後在應用裡面進行數據處理。

4.有緩存就是吊,不服數據庫你自己做啊。

>>>aruis

sql裡面用上with,可讀性可以大大提高,所以sql的維護成本並不一定比在程序裡拆成多步實現要高。

至於用不用得上索引,豈可一概而論,這要看sql的寫法跟表設計索引的具體情況。

直接武斷下結論說用程序跑速度更快的,我覺得都不太可信。通常來說,sql寫得夠好,會比在程序裡面算要快。因為數據庫就是吃這碗飯的,要是group by還沒有程序跑得快,豈不是人人都可以設計數據庫了。

樓上有個老哥說的對,建議兩種都試試,實踐出真知。

@melon_jj:想用 MongoDB 取代 MySQL 可以嗎?

有可能會出現哪些問題?

>>>lee_oschina

一是要看你的業務類型,二是不能用MYSQL的思路來建MONGO

>>>sxgkwei

適用場景不同,一般對事務性要求不強的領域,比較適合MongoDB。如果對一系列增刪改有強制事務原子性要求,那顯然要數據庫支持事務回滾的啊,還是MySQL吧。

還有你得忍受一些小bug之類的,畢竟MongoDB發展時間沒MySQL長,出個小坑也可以理解。或者你還得承受去年那種MongoDB數據洩漏造成的惡劣影響的損失之類的。其它的,就沒什麼了。

>>>烏龜殼

4.0 之後,理論上的替代已經成立了,核心機制已經支持事務。

實際我還沒試過不知道情況。

不過最重要的一點樓主沒說,為什麼要換? 出於什麼原因考慮?

@smallfatQQ:提取兩個txt文件中有相同文字的那行數據,並以同樣格式存儲到另一個新的txt文件中

我有兩個文件:一個文件叫list.txt裡面包含n個id,每個id一行

ZINC042-03-483
ZINC268-95-155
ZINC036-51-026

一個文件叫data.txt裡面包含有n多行(上億行)的信息,其中有些行中包含了list.txt中的id信息,如下僅列部分數據:

123 ZINC268-95-155
2323 ZINC036-51-026
231 ZINC042-03-483
1 ZINC042-03-4444
444 ZddCyyy
6326 dgag
32323 yyj
211 ddghghd
3546 ZINC036-51-026

我希望通過list.txt文件裡的3個ID在data.txt文件查找相對應的信息,然後將data.txt中整行信息都輸入到一個新的new.txt文件裡。如果在list.txt中信息未在data.txt中查到,就在new.txt中僅顯示list中的ID

熱心的 oscer 幾經修改終於解決了樓主的問題,建議大家點進原貼看看~

>>>tcxu

readStream1 = open("list.txt", "r");
context1 = readStream1.read();
a = context1.split('\n') # 從文檔 list.txt 取得的關鍵詞數組
size = len(a)
b = [ 0 ]*size # 對應關鍵字數組 a,創建一個整型數組 b,每個元素的初始值為零。
result = open("new.txt","w")
fo = open("data.txt", "r")
try:
while True:
line = fo.readline()
if line:
index= 0
for v in a:
if line.find(" " + v) > -1:
v = v + " " + line
b[index] = b[index] + 1
result.write(v)
index = index + 1
else:
break
finally:
fo.close()
# 最後檢查每個關鍵字是否在數據文檔data.txt都有數據對應
index=0
result.write("\n")
for value in b:
if value == 0:
out = a[index]+" NA NA\n"
result.write( out )
index = index + 1
result.close()
readStream1.close()

list.txt

開源社區8月問答合集:想用 MongoDB 取代 MySQL 可以嗎?

data.txt

開源社區8月問答合集:想用 MongoDB 取代 MySQL 可以嗎?

new.txt

開源社區8月問答合集:想用 MongoDB 取代 MySQL 可以嗎?

>>>公孫二狗

把 2 個文件的信息都先處理一下,按 ID 排序生成新的文件,然後對新文件再進行匹配比較

還有一種方式就是先導入數據庫,使用多表關聯查詢導出數據

>>>sxgkwei

大量數據時,僅程序可能不太可能能實現。因為無論什麼語言,就把這些數據載入內存,它也要消耗很大空間啊。所以,可以考慮使用數據庫,逐行讀取批量插入,先把數據都插入數據庫兩個表,然後,使用 sql 就能比對出你要的結果。

@laozhong__:阿里RDS一張200w的訂單表,部分數據查詢快,部分數據查詢慢,求解?

查詢字段是個datetime格式的create_time,有索引,全部都是按照主鍵id倒序排,如果去除id倒序排的話沒有問題:

基本格式如

​​​​​​​SELECT * FROM `tb_orders` WHERE `create_time` BETWEEN '2018-01-21 00:00:00' AND '2018-01-21 23:59:59' ORDER BY `id` DESC
1. `create_time` between '2018-01-21 00:00:00' and '2018-01-23 23:59:59' 耗時2.343s 結果集22099條
2. `create_time` between '2018-01-21 00:00:00' and '2018-01-21 23:59:59' 耗時2.390s 結果集8956條
3. `create_time` between '2018-07-21 00:00:00' and '2018-07-23 23:59:59' 耗時0.250s 結果集15403條
4. `create_time` between '2018-07-21 00:00:00' and '2018-07-21 23:59:59' 耗時0.015s 結果集5638條

給我的感覺,是1月份的數據量差不多,但是慢很多,7月份的快很多!其他月份也有快有慢!

表數據是187w多,40多個字段,pma顯示大小為數據440MB,索引256MB,innodb引擎;

這會是什麼原因呢!

explain如下,為何會有filesort :

EXPLAIN SELECT * FROM `tb_orders` WHERE `create_time` BETWEEN '2018-01-21 00:00:00' AND '2018-01-21 23:59:59' ORDER BY id DESC
開源社區8月問答合集:想用 MongoDB 取代 MySQL 可以嗎?

問題補充

// 1. 改用create_time排序,能解決查詢慢的問題

// 2. 如果只查詢id列,或者create_time列,速度快,沒問題,我補充了profiling數據

/ 3. 我感覺現有的回答都沒用很好的解釋,1、4月份的數據慢,其他的快,當然17年的幾個月就更加慢了,儘管量還少些!說緩存也對吧,但是這麼點數據量,實在不應該啊!

>>>OSC_YIdCag

SELECT t1.* FROM `tb_orders` t1 INNER JOIN (SELECT `id` FROM `tb_orders` WHERE `create_time` BETWEEN '2018-01-21 00:00:00' AND '2018-01-21 23:59:59') t2 ON t1.id=t2.id ORDER BY t1.id DESC

>>>我叫金正恩

訂單ID使用10位數的時間鏃 加上固定位數的隨機數

查詢時候時間轉成時間鏃補0站位,根據ID卡範圍,千萬級別數據也是毫秒級查詢

自增ID卵用沒有

開源社區8月問答合集:想用 MongoDB 取代 MySQL 可以嗎?

開源社區8月問答合集:想用 MongoDB 取代 MySQL 可以嗎?

開源社區8月問答合集:想用 MongoDB 取代 MySQL 可以嗎?

模擬數據是2018-05-30至2018-10-05,共計11100040條

查詢數據範圍內任意一天 ,內網這個開發用的庫比較繁忙0.42秒

>>>魔力貓

因為MySQL只能使用一個索引,已經用了createtime進行範圍查詢了,order 的又是另一個字段,索引無效。

接下來的速度其實就是看數據分佈情況和內存情況了。日期近的,大概率也被別的業務調用,所以大概率內存有緩存。返回數量少或者正好當時內存比較空餘,在內存中運算不使用或者少使用臨時文件,就快一些。

@HaleyZhang:sql 優化通配符 % 不能放詞首

優化中說%最好不要出現在詞首,那應該怎麼寫查出包含hh的name呢?

>>>icytail

SELECT *
FROM car
WHERE INSTR(NAME, 'hh') > 0;

>>>魔力貓

​​​​​​​百分號這種通配符最好不要出現在開頭的意思,是因為這樣寫,索引無法匹配,而不是不能這麼寫。這麼寫本身,是符合語法的,但是性能是否能滿足你,就要看實際運行情況了。

百分號、問號,這樣的通配符,如果只出現在結尾,普通索引可以掃描。如果只出現在開頭,反向索引可以掃描。如果前後都有,那麼索引就徹底涼了。

職業生涯問答

看看程序員關心的職業生涯問題都有哪些 ——

@老朽怕是要破戒了:公司給股份1%,但是要求降工資3000,強行想拉我上船,求指點

背景:初創公司,團隊一二十人,二三線城市,公司股權結構大概是大boss 80% ,小boss 17, 還有一個小機構當初也投了10萬塊錢,佔 3%,成立不到1年,當初大概總共投110萬的樣子,現在打算再投100w,目前公司肯定還是虧損的,主要是人員工資成本,公司發展方向個人感覺總體還行。

剛入職的時候,是以技術合夥人的角色應聘的,當時要求工資16.5K ,老闆說要給期權,大概1%的期權,但是大概一年半之後才轉股份,工資就壓倒15K,當時勉強同意了,

這不才轉正呢,公司表示對我的能力認可,怕我對當前工作不能完全上心,想拉我上船,已創業者的身份加入,說直接給我1%的股份,原先的期權不變,到時候期權到時間,一共2%的

但是說光給乾股怕我沒啥感覺,說需要放點血,所以,需要把我的工資壓到12K

現在想問問我大佬們,這種情況,有沒有什麼好的建議和意見

>>>翔少

光給乾股怕我沒啥感覺,說需要放點血

狗屁理論,你就說沒感覺不是因為沒放血,而是因為乾股不夠多

>>>暗影風暴

以股份為由,限制薪資,限制自由的都是耍流氓,不尊重人的表現

>>>何勇傑

前面幾個哥們都分析得很到位,股權是一種激勵措施。公司合夥人降薪入股是對公司發展看好和投入的表現。別人其實也怕技術只拿錢不放血,到時候不能共患難,直接可以去下一個公司繼續做技術拿錢。

願不願意放血,這個你其實需要多方面去分析的。你作為技術合夥人,看來公司的發展有很大部分是依賴於技術平臺的好壞,那麼你在公司經營過程中,參與了多少事務?如果大小事情你都知曉,與你工作相關的事務來一起討論,並尊重你的意見。那麼還是可以的。(避免在隱瞞你的情況下,公司負債,這個你需要共同揹債的)另外還需要談好,在什麼條件下以什麼形式來分紅。因為你想做到上市再分紅,那麼你這個以股份得到收益風險係數會更大。

另外,對於技術最終只佔股2%,確實是非常少的。不過好的做法就是算好目前的估值。不要贈予的方式,拿每個月工資的一定比例來購買股份。一般好一點10%股份左右,不過考慮到你前期創業沒參與投入,不算創始人。個人做為技術合夥人拿到5%,應該算可以的。

以目前這種股份比例,加上口頭上說是贈予,背後又要降薪的做法。就是表面上做的好看,結果覺得不划算,又要以共同奮鬥為目標來降薪,這種做法就是忽悠的方式,個人覺得沒有誠意。他為你著想的部分不足。

請他表示一點誠意!

>>>黑狗

這種你佔了大便宜了

我覺得你應該這樣,花1200塊開一個公司,註冊資金搞個200W吧,每個月花200塊找個財務代賬,估值200W,折價賣給他49%股份,只收他20W。你們還談啥工資啊,你給他股份啊,他對你這麼好你可不能虧了他

>>>newzai

不能明說拒絕, 否則你就在公司混不下去的。委婉一點拒絕,,這個時候,要哭窮,自己啥房貸啊,車貸啊,老婆,子女的生活費啊,每月開銷到手的錢,基本精光,如果少點3000元,日子沒法過了。

然後再說,,自己也想和公司一起發展。但是現實生活壓力太大。。。

@OSC_GALyfe:去給政府做項目的公司好嗎?

目前有兩家公司可選 座標西北地區,我是其他語言轉java

幾個公司和鐵路合資 新創立的 “創業公司”,主要改造鐵路老舊的物流系統做一個打通鐵路物流信息的一個多聯式運輸信息平臺產品,盈利方式未來企業付費使用這個物流信息產品,團隊年輕只用新東西新技術Git、docker,工作環境也可以,但是自己帶電腦,每個月補電腦費,加班可以回家做,因為鐵總數據外網斷開所以要連內網VPN。各種補助補貼多 固定每月800-1300元,交通不方便在開發區。

中科軟,現在需要招兵買馬,有大量項目, 要做好幾年,在本地給zf做wei穩an防等項目,據說也是用新技術、新東西,版本用SVN,說有大數據,每週Google看板方式交流,但是我有點懷疑給zf做東西技術含量問題。電腦ThinkPad統一配,不能連公網,最好自己要準備個電腦網上下第三方包等,然後用光盤傳文件。每月補貼較少,交通方便點,在市區。補貼只有餐補300,說是然後做項目功能做的多以後就拿的多。

兩家薪資一樣,鐵總創業公司補貼多 薪資晉級規則明確,實發會多。 做項目公司沒有明確的薪資規則,只是說多勞多得,可能會駐場,涉密電腦不能上網,下載更新包和第三方組件感覺不方便,沒有這方面經驗,然後就是工作環境不一樣。大家給個意見

>>>隨機9380fa

皮包公司,千萬不要去。這個工作的性質就似一個包工頭通過關係,拉到一個工地項目,然後拉一幫農民工去搬磚,包工頭為了追求利潤,就會不斷叫民工加班加點去完成個工地項目,質量能用幾年就行了,項目交付後包工頭分了大錢,人員解散,工地出事故死人的話,包工頭早就遠在天邊了。

>>>walykyy

真的不建議去政府企業,我就是剛辭職的,雖然是實施類的,客戶要求真的多,隨時都有可能要求改動,遇到有想法的你會覺得上天入地都沒有門,根本就不可能實現,脾氣不好的罵人跟罵孫子似的,我在鐵路和政府財政幹了11年多了

@IT菜鳥進山:一個什麼樣的工作環境適合人成長,對於技術人員來說?

行業方向感模糊,技術不知道怎麼提升,但是閒下來又很慌,我該怎麼辦

>>>netkiller-

環境是自己創造的,不是別人給與的。

我十年如一日的,給自己設置目標,培養自己的興趣點,不斷打怪升級,才走到今天。

>>>暗影風暴

成長和環境有關,但並不是唯一,核心在自己。

不管什麼樣的公司都有可以學習的地方,就看這些點是不是自己渴望學習的罷了。

技術是工具,要麼自己打磨(可能慢一些),要麼有人領著你告訴你怎麼打磨(快一些),但是這些歸根結底都是自己打磨。

業務也是技術成長的一個不可或缺的發力點,要想紮根一個行業,業務不精那是不行的。

綜上,關鍵是看自己對技術成長的看法和實際行動。公司環境只是一部分而已。希望對你有所幫助

>>>sxgkwei

一般來說,適合成長的公司,其實核心就一點:長期浸淫一個項目的開發。不管是互聯網公司還是自主產品公司,一個人進去之後,都是在持續做一件事兒,這樣才能鍛鍊深入思考各種套路的思維方式。

不適合成長的公司,當然就是反方向的:始終在換開發的項目。外包,接項目來做2/3月完工的,或者不是外包但把你派到各個客戶現場去2,3個月給客戶開發完一個項目的。核心就是短期項目,這種項目一般只能 CRUD 下數據庫,ctrl+c/v 了,沒人在乎誰離開,公司內部也不在乎各種寫法的優化與效能。所以去了就是碼畜。

>>>岑臣

整個公司幾十號人,十個產品,八個運營,七個客服,一個總監,兩個老闆,就你一個程序員!前後左右上下各端都等你來寫!你每天都要面對各種突發情況,需求多到你做不完,而且隨時有重構風險的環境!

>>>南山北寺

工資高到你捨不得走,還有一群傻逼隊友嗷嗷待哺的環境。

你也希望自己的提問/回答上榜?歡迎大家前往>>>技術問答區,多多提問,多多回答~!


分享到:


相關文章: