鍍金池/ 問答/ 數(shù)據(jù)庫問答
硬扛 回答

在mysql官網(wǎng)上看到的
On the other hand, you should not use mysql_use_result() for locking reads if you are doing a lot of processing for each row on the client side, or if the output is sent to a screen on which the user may type a ^S (stop scroll). This ties up the server and prevent other threads from updating any tables from which the data is being fetched.

魚梓 回答
select *,count(*) from A,B where A.cid = B.cid and A.uid = B.uid
鐧簞噯 回答

僅從MongoDB的角度說明這種東西可以怎么存。至于別人到底是怎么存,我們是不知道的。

關系模型存法

不多介紹,可以按照范式設計成跟關系數(shù)據(jù)庫一樣的表結構來存儲,大概是:

{
    _id: ObjectId(...),
    comment: "...",
    time: ISODate(...),
    user: "...",
    musicId: "...",
    ...
}

如果用慣關系數(shù)據(jù)庫的用戶,這樣的做法簡單自然。在現(xiàn)在討論的場景下,這樣沒有太大的問題,在數(shù)據(jù)量大時可以使用分片來達到水平擴展以應對數(shù)據(jù)量的增長。
不過仍有可以改進的地方。這要從MongoDB的模型設計來講起。簡單地說,MongoDB是實用主義,怎么方便怎么來,怎么快怎么來,完全不應該受范式的約束。但這也意味著你的模型要從應用的需求出發(fā)。僅從上面截圖的信息,可能有2個不同的需求:

  1. 評論
  2. 點贊

考慮到評論和點贊都有可能上萬甚至上十萬百萬,它們以單獨的集合來存放會比較合適。但是為了讀取和存儲效率,我會考慮把多條評論壓縮到一起,這種方式通常稱為分桶(bucket)。

非關系模型存法

{
    _id: ObjectId(...),
    musicId: "...",
    // 根據(jù)需要可能將音樂本身的一些數(shù)據(jù)冗余進來
    musicName: "...",
    comments: [
        {content: "...", time: ISODate(...), user: "..."},
        {content: "...", time: ISODate(...), user: "..."},
        {content: "...", time: ISODate(...), user: "..."},
        ...
    ],
    count: 10, // 該桶內已有10條comments
}

comments的數(shù)據(jù)量我會考慮一頁會展示多少評論(比如30條),那么在添加評論時可以有:

db.comments.updateOne({
    musicId: "...",
    count: {$lt: 30}
}, {
    $push: {
        comments: {content: "...", time: ISODate(...), user: "..."}
    },
    $inc: { count: 1 }
}, {
    upsert: true
});
// 優(yōu)化查詢速度會使用到索引:
db.comments.createIndex({
    musicId: 1,
    count: 1
});

在查詢時總是只需要最多取最新的2條記錄就可以查到第一頁:

db.comments.find({
    musicId: "..."
}).sort({_id: -1}).limit(2)
// 這個查詢需要索引
db.comments.createIndex({
    musicId: 1,
    _id: -1
});

注意_id的高4位是時間,所以是可以排序的,其順序就是時間順序。
點贊的問題可以通過類似的方式實現(xiàn),就留給你自己思考了。

墨染殤 回答

你說的思路比較亂,先聚焦一下問題:

如果是持續(xù)的寫入壓力大,且超過單臺服務器磁盤IO寫入能力,最簡單的辦法就是mysql分為多個數(shù)據(jù)庫,保證數(shù)據(jù)能分布不同的磁盤設備上,以提升寫入的能力。

如果只是高峰期的寫入壓力大,可以考慮讀寫主要靠緩存的方案,后臺同步到數(shù)據(jù)庫,但這樣對緩存的可用性、數(shù)據(jù)預熱方面的要求較高。

java方面的優(yōu)化,主要是提高接入能力,和后端數(shù)據(jù)庫是否能支持大數(shù)據(jù)寫入沒關系。

兔寶寶 回答

table_A,table_B

DB::name("table_A as a")
->join("table_B as b","a.id = b.**_id","left")
->feild("a.is_visit as is_visit_a ,b.is_visit as is_visit_b")
->where([
"a.is_visit" => 1,
])

問題描述的真費勁啊

玩控 回答

case when 語句是無法實現(xiàn)的, A 關聯(lián) B 后是多條數(shù)據(jù), 那么 case when 出來的結果沒法合并成一行.

如果說, 條件固定 也就是 paraid 只有

當paraid=100時,別名為 name
當paraid=103時,別名為 companyName
當paraid=106時,別名為 companyAddress
當paraid=109時,別名為 avatar
當paraid=112時,別名為 companyAbout

或者是確定的情況下, 可以通過下面的 sql 語句實現(xiàn)

select
a.id, b.info as name, e.info as companyName
from a
left join (
select listid, info from b where paraid=100
) as n on a.id=n.listid
left jion ( 
select listid, info from b where paraid=103
) as e on a.id=e.listid
left join ...

一對多關系, 要合并數(shù)據(jù) sql 實現(xiàn)可以考慮此方法.

終相守 回答

$map,$reduce,$filter (segmentfault無法正確轉義美元符號,湊合看吧……)這些運算符在很多場景下可以幫助我們避免$unwind,語法請參考下文檔。對于你的要求,可以用$filter直接解決問題:
文檔格式

{
    "_id" : ObjectId("5a6d7c5e0664b8343e7e126b"),
    "keyID" : "111111111111",
    "price" : 123,
    "remark" : [
        {
            "city" : "beijing",
            "point" : "A"
        },
        {
            "city" : "shanghai",
            "point" : "A"
        },
        {
            "city" : "guangzhou",
            "point" : "C"
        }
    ]
}

aggregation寫法

db.test.aggregate([{
    $match: {
        "remark.point": "A"
    }
}, {
    $project: {
        _id: 1,
        keyID: 1,
        price: 1,
        remark: {
            $filter: {
                input: "$remark",
                as: "remarks",
                cond: {
                    $eq: ["$$remarks.point", "A"]
                }
            }
        }
    }
}])
吃藕丑 回答
  1. oplog 在 MongoDB 里是一個普通的 capped collection,對于存儲引擎來說,oplog只是一部分普通的數(shù)據(jù)而已。所以,在開啟復制集的時候,oplog應該會在內存里,因為oplog會經(jīng)常性地被重放來達到數(shù)據(jù)同步的作用。
  2. 第二個問題搭車期待大?;卮稹?/li>
朕略傻 回答

你是后端的話,你返回給前端的時候,你把置頂?shù)姆旁跀?shù)組的第一位,然后返回給前端,前端盡量不去做這些處理,因為很多置頂?shù)臅r候后端處理會方便很多

若相惜 回答

感覺還不如在業(yè)務層去做
先把最新的id 放進去 循環(huán)查詢
直到 時間過期 或者 沒有 更久的數(shù)據(jù)
話說 客戶更新卡號表 沒有 客戶字段 也是 真厲害

不討囍 回答

1.熱門詞對應的數(shù)據(jù)或者搜索歷史對應的數(shù)據(jù)緩存到redis中
2.使用sphinx

蟲児飛 回答

Image手機版不好打字,只好把自己的文檔截圖了

局外人 回答

基本沒區(qū)別,只是計算機底層對兩種字符分解結果不一樣,可以忽略

來守候 回答

樓上說的沒錯,如果設計到時區(qū)問題,就不能存date了。時間戳是個人認為最好的解決辦法

萌吟 回答
  1. 登錄之后把用戶信息寫到redis/memcached這種緩存里面
  2. 所有計算都基于緩存計算
  3. 后臺進程定期把緩存數(shù)據(jù)存入數(shù)據(jù)庫

你試試看可不可以達到尼的效果?

我不懂 回答

舉個用戶表的栗子:

id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT
username CHAR(15) NOT NULL
password CHAR(15) NOT NULL
UNIQUE (username)

現(xiàn)在主鍵是id,索引是username,對于InnoDB來說實際上有兩個索引:

id -> (username, password) // 以下稱為PK
username -> id             // 以下稱為UK

如果你這么查:SELECT id FROM user WHERE username = ...,那么MySQL只會查UK,而不會去查PK;
如果你這么查:SELECT id, password FROM user WHERE username = ...,那么MySQL會查一次UK,得到id后再查一次PK。

如果你要優(yōu)化第二句,可以多加一個索引:


KEY (username, password)

這樣就有:

(username, password) -> id // IDX

如果你再這么查:SELECT id, password FROM user WHERE username = ...,MySQL就只需要查IDX,而不用再查PK和UK了。

情已空 回答

jackson 字段動態(tài)過濾

https://github.com/bohnman/squiggly-filter-jackson
https://github.com/narusas/SpringMvcJacksonFilter
https://github.com/shihyuho/jackson-dynamic-filter

  1. 使用AOP;自己定義注解,然后在返回的時候加上需要過濾的字段.

這是我的工具類 
https://github.com/yujunhao8831/spring-boot-start-current/blob/master/aidijing-common/src/main/java/com/aidijing/common/util/JsonUtils.java
  1. 實現(xiàn) ResponseBodyAdvice<T> 接口,如果這樣,那么就需要使用統(tǒng)一的返回值類型,把之前的返回值包裝起來.
    這樣在Spring Response 寫出去之前,你可以對這些數(shù)據(jù)進行處理,還是使用jackson的過濾特性.
    我之前就是這樣做的, https://github.com/yujunhao88... 你可以參考下

  2. 返回之前就立馬進行過濾.
    我之后準備采用這個, https://github.com/yujunhao88...
    你可以參考下,不過這不是最終的,還在完善中