iT邦幫忙

1

純討論,在程式中使用兩種DB

最近因興趣使然,正在寫Discord bot 使用nodejs環境與discord.js

然後想問的是,在程式中使用兩種DB會有什麼不妥嗎?

主要原因是我的機器人有兩種功能
1.查詢一款遊戲中的角色資料,就是寶可夢
2.透過記錄使用者說話次數,提升使用者現在配戴的寶可夢的等級

那我看了一些資料說到 1 功能這種不太會變動的資料,而且表與表之間的關聯性相對大的使用R-sql(mysql)比較好
而 2 功能這種需要快速讀取與儲存的則是使用NoSQL(mongoDB)

而功能2跟1會有重疊到的需求就只有,一個使用者同一時間身上只能帶一隻寶可夢,而如果要切換寶可夢的話,就會先利用功能1查詢是否有這種寶可夢存在,若存在才可切換這樣。

因此我想問,如果是上述情況的話,各位會怎麼做? 是會就分成兩個DB去存,還是會傾向於只使用一個,而把另一個的資料倒過去另一邊?

純粹想問問各位的意見,謝謝。

技術債的開端
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
3
㊣浩瀚星空㊣
iT邦大神 1 級 ‧ 2021-01-04 10:02:54
最佳解答

基本來說,一般並不太建議就是了。
畢竟不同sql來說,少了庫與庫之間的關聯是很麻煩的事。

且就效能性來說,真的用不同的sql就會來得比較快?
這也是一種未知性。

我知道有一種設計的方式,是給app相關用的。web相關則比較少看這樣的技術。
就是前端會有自已的sql放在前端上。

主要搜尋及查尋在前端上處理。只有在固定情況下才會與後端的sql同步更新處理。
會這樣做的原因。就如你說到的效能問題。
畢竟不需要一直跟後端請求。理論上來說一定會快很多。
但畢竟是在前端,相關資料的安全性就有待考量。

另外一種是不得已的做法。我早前曾經碰過。不過因該是跟你的主題比較無關。
就是遊戲的app是用mssql處理的。但web是用mysql處理的。
當時的做法並未將其不同的sql同步共用。
而只是各取所需處理。

看更多先前的回應...收起先前的回應...

SQL寫在前端?
會不會變成駭客的SQL猜字遊戲?

放心,一定不會,因為不需要猜
哈哈哈。

前端後端兩邊各放DB我還是第一次聽到,只聽說過有利用前端cache先跟後端拿近期資料的...感謝大大的回覆

至於效能問題其實我也是在思考,因為目前是用mysql,每次記錄說話就send一次query總感覺很slow啊...

順便問問,基本上如果我只是個人寫這樣的機器人用mysql應該不至於有什麼商業授權問題吧? 但如果未來有需要donation功能會不會違反相關法規?

其實大多數看到的,的確是你說的cache。
但其cache也是可以nosql的方式處理的。
雖然說是nosql。大多數來說都是文字檔居多也沒錯。

記錄方面,用我以前的經驗。並不會每一次都傳送。或是延遲式傳送。

第一種是會先將記錄存在前端上。一段時間統一傳送。
這招雖然可以降低效能。但容易發生資料遺失的問題。
因為緩存的記錄,如果發生不可預期的錯誤或問題。
就會變成消失沒傳了。

第二招則是一樣傳送到後端。但不立即做sql的操作對應。
一段時間後才做儲存。
這也是降低資料庫效能的一招。但也是有風險。
但比起第一招還是好很多。

如果資金足夠的情況下。一般還是會建議多資料庫並做讀寫分離。
可以確保資料完整性,也比較不擔心效能的問題。
缺點就是,成本比較高。

一般來說,像我說的前端sql跟後面說的兩招。
都是在考量成本的情況下。不得已接受其風險。
由其是那種一秒有100多筆以上記錄的。更是需要。
如果1秒最多才10筆左右的。才並非是很頻繁性。
大多數來說都還不需要去考量這些。

ps:以上的筆數是指單一人的發送筆數,而非server接受到的筆數。
理論上server接收的同時筆數,盡量最高不要每秒500筆以上。
除非你機器夠強。

大概了解了,之前是想說就是一樣先傳到後端但不立刻做sql處理這樣。
但是mysql又沒有大量UPDATE的方法 用loop去UPDATE好傻的/images/emoticon/emoticon02.gif

不知道大神有沒有辦法/images/emoticon/emoticon41.gif

其實大多數來說。這幾招都是針對「新增」。
如果是update的話...

那還真的沒啥很有效的招。
因為update的東西就算緩存後推送,對資料庫來說並沒有很有效的緩解。

只能從設計規劃上下手了。讓update的動作想辦法不要太過頻繁。

這是個苦差

將user:說話次數單獨存成另外一張表然後每次都把表清空後重新Insert進去呢?

別~~~

這招很早期我以前的工程師真的這樣幹過。
但那時我不知道他是用這招。

直到某一天查了記錄。io常很莫明的提高。
高到有點不太合理。
我就下追蹤了。

果不其然。我看到了del... inn.....
你xx的。還好機器夠強。
要不然死給你看。

怕豹,這下子我還真只能想辦法UPDATE了

DennisLu iT邦研究生 1 級 ‧ 2021-01-06 10:01:46 檢舉

清空 寫入 清空 寫入 別這樣做
但我還是看過有人這樣做
遇過寫程式的來怪DBA
DBA說資料庫沒問題,
看了一下 搖頭 說出寫程式的平常怎麼用資料庫
處理掉他常用的Table後,之後還是這樣用
反正有事再找DBA...

所以Server建議規格都拉很高...

2
海綿寶寶
iT邦大神 1 級 ‧ 2021-01-04 12:33:06

我想到一個類似的問題
「同時使用兩家銀行的帳戶會有什麼不妥嗎?」

我有一筆閒錢,放在 A 銀行定存
較常存提的生活費,放在 B 銀行活存

ok 的
/images/emoticon/emoticon08.gif

至於為什麼要把錢放到兩個銀行而不集中在同一個銀行
那就是每個人的考量因素不同

如果是我,如果可以的話
我希望全部的錢都集中放在同一家銀行裡

看更多先前的回應...收起先前的回應...

雖然很像 不過我想大概是更加程式面的問題
用您的例子來說的話大概就像
A銀行ATM很少,要存要領要跑很遠,但是利息高。
B銀行ATM很多,要存要領很近就可以,但是利息低。

今天我有閒錢跟生活費,如果確定分開存,想當然應該閒錢存A銀行,生活費存B銀行,但有時候生活費有剩的話就會想當閒錢存起來,因此又要跑一趟A銀行。

如果今天兩家都要放,就會變成兩頭跑,如果只放一家,放B銀行利率太低,放A銀行又跑太遠,大概是這種感覺吧/images/emoticon/emoticon02.gif

ckp6250 iT邦好手 1 級 ‧ 2021-01-04 15:52:05 檢舉

假設這筆閒錢是幾十百億的話,當然考量幾家銀行去存。(錢太多銀行不肯收)
若只有幾十幾百的話,那就不用傷這個腦筋了。

賽門 iT邦超人 1 級 ‧ 2021-01-05 08:44:33 檢舉

因銀行定存利率高, B銀行跨行提款十次內免手續費.
發問人用DB的方式, 海綿寶寶存錢的方式, 都行之有年, 所在多有.
問題只在看你方便以及個人考量.

有錢人才不會把所有錢放在同一個帳戶@@..
因為銀行利息有存款限制~所以大都分散各銀行存放生利息...

0
tunin
iT邦新手 4 級 ‧ 2021-01-04 18:56:57

針對你的兩個需求而言,其實使用一個資料庫就可以了,並沒有需要特地分成兩個不同資料庫儲存的狀況。
mongodb也能做到關聯查詢,不是說只能用關連式資料庫來實現。
就個人經驗來看,同一個系統使用兩個不同的DB,大多是基於效能上的要求,比如說mysql的資料量太大了部分關聯查詢變得太慢,所以可能預先整理非即時的資料到mongodb做快取。
另外也可能是基於功能上已經做切分了,使用微服務的概念將整個系統分為多個微服務,各服務使用的DB就依據該服務的需求考慮。
當然大多數的時候開發初期是基於團隊是否熟悉該技術來考慮使用的資料庫,一個新的專案先能上線可能是主要考量,除非評估已經明確知道該架構需要能負荷的需求有多大,否則先進入市場才是關鍵,效能問題初期都可以透過設備解決。

1
japhenchen
iT邦超人 1 級 ‧ 2021-01-05 08:12:36

我這邊的情況,就有遇到在兩套資料庫系統的情況,我要把MSSQL人資系統裡的新進人員,把他們的email加進webmail的的通訊錄上,通訊錄是mysql格式.....

我用python定時每天晚上12點半跑一次

#!/usr/bin/env python3
# -*- coding:utf-8 -*-

import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning)

import os,re
import pymysql 
import pymssql


def main():
    reNum = re.compile(r'^\d+$')
    mylist = list()
    mslist = list()
    myconn = pymysql.connect("127.0.0.1", "nameUser",
                             "pwUser", "webmaildb",cursorclass=pymysql.cursors.DictCursor)
    msconn = pymssql.connect("172.16.10.200", "dbaname",
                             "dbapw", "HR")
                            
    mycursor = myconn.cursor()
    mscursor = msconn.cursor(as_dict=True)
    #..............

後面還一大堆就不拿出來秀了,我只是想講,沒人說用多個DB不可行,但要看真實情境是如何,如果資料都你建的,那用多個DB只會徒增管理上的麻煩,我會用XXXXTYPE欄位來區別,而不是一個功能一個DB來區分,當然我也見過有人以專案案號來動態建DB的例子,當你發現你的SSDT在打開那個成千上萬個DB的資料庫超級慢時,你就會理解我心裡的OS...

而我會用這個例子來說明不只多個DB,還是不同品牌間的SQL的應用,只是因為這兩套資料庫都不是同一人寫的,為了目的,只好不擇手"斷"

1
賽門
iT邦超人 1 級 ‧ 2021-01-05 08:55:11

沒人阻止你用兩個DB, 這樣做, 很多.
以前參加政府標案, 還有用DB綁標的, 在綁標的規格中, 會描述一種情境, 然後要求要在幾微秒內完成, 這個Oracle最會了.
只是, 如果只是貪圖那幾微秒的交易速度比較快, 以你描述的需求, 可能得不償失.
因為, 如果你把兩個DB安裝在同一台Server中時, 所謂一種DB比另一種DB快幾微秒的論點是完全不存在也不可靠的.
你知道那個快幾微秒的交易環境是用了多少精神去Performanec Tuning才得到的結果嗎?
通常我會建議, 如果沒有特別的需要, 像是超大型DB的需求, 或是超大量的交易需求, 我們通常用一種DB就夠了.
接下來的問題是, 你要如何Performance Tuning, 取得最佳效能反應.

其實他不是在「問問題」
心中已有定見
只是來「純討論」的而已
/images/emoticon/emoticon39.gif

我要發表回答

立即登入回答