鍍金池/ 問答/ 數(shù)據(jù)庫問答
你的瞳 回答

FIND_IN_SET() 這個函數(shù)解決了

幼梔 回答

在 sql 下, 方案2更好. 在 mongo 下, 方案1更好.
不知道你的這個項目中有沒有用戶權(quán)限組的概念.
如果有權(quán)限組的話, 就是一個權(quán)限組的 collection 里面, 每個權(quán)限下保存了一個菜單項的數(shù)組.
如果沒有權(quán)限組的話, 就可以按照你說的方案1, 在每個用戶表里, 或者單獨的用戶權(quán)限表里, 保存一個菜單數(shù)組.
當(dāng)然, 保存菜單項的 id 數(shù)組或許更合適.

mongo 里面數(shù)組也是可以建立索引的, 查詢也很方便.
另外, 也可以參考 mongo 自身的權(quán)限系統(tǒng), 其權(quán)限設(shè)置也是保存在 mongo 數(shù)據(jù)庫內(nèi)的, 通常都是 admin 庫下的 users 表. 如果你的 mongo 開啟了權(quán)限管理, 并且權(quán)限庫名字就叫 admin, 則可以用以下命令查看:

> use admin
switched to db admin
> show users
{
    "_id" : "admin.admin",
    "user" : "admin",
    "db" : "admin",
    "roles" : [
        {
            "role" : "root",
            "db" : "admin"
        }
    ]
}
{
    "_id" : "admin.migration",
    "user" : "migration",
    "db" : "admin",
    "roles" : [
        {
            "role" : "backup",
            "db" : "admin"
        },
        {
            "role" : "read",
            "db" : "local"
        },
        {
            "role" : "read",
            "db" : "some_database"
        }
    ]
}
{
    "_id" : "admin.sys",
    "user" : "sys",
    "db" : "admin",
    "roles" : [
        {
            "role" : "__system",
            "db" : "admin"
        }
    ]
}

以上輸出為示例. 可以看到官方存儲權(quán)限的方案也是用數(shù)組.

參考:
mongo 官方文檔 - 用戶權(quán)限管理
mongo 官方文檔 - 數(shù)組索引

終相守 回答

$map,$reduce,$filter (segmentfault無法正確轉(zhuǎn)義美元符號,湊合看吧……)這些運算符在很多場景下可以幫助我們避免$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"]
                }
            }
        }
    }
}])
玩控 回答

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

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

當(dāng)paraid=100時,別名為 name
當(dāng)paraid=103時,別名為 companyName
當(dāng)paraid=106時,別名為 companyAddress
當(dāng)paraid=109時,別名為 avatar
當(dāng)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 ...

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

鐧簞噯 回答

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

關(guān)系模型存法

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

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

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

  1. 評論
  2. 點贊

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

非關(guān)系模型存法

{
    _id: ObjectId(...),
    musicId: "...",
    // 根據(jù)需要可能將音樂本身的一些數(shù)據(jù)冗余進來
    musicName: "...",
    comments: [
        {content: "...", time: ISODate(...), user: "..."},
        {content: "...", time: ISODate(...), user: "..."},
        {content: "...", time: ISODate(...), user: "..."},
        ...
    ],
    count: 10, // 該桶內(nèi)已有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),就留給你自己思考了。

吃藕丑 回答
  1. oplog 在 MongoDB 里是一個普通的 capped collection,對于存儲引擎來說,oplog只是一部分普通的數(shù)據(jù)而已。所以,在開啟復(fù)制集的時候,oplog應(yīng)該會在內(nèi)存里,因為oplog會經(jīng)常性地被重放來達到數(shù)據(jù)同步的作用。
  2. 第二個問題搭車期待大?;卮?。
糖果果 回答

如果是網(wǎng)站,還是有可能并發(fā)的,因為php會不同訪問的用戶創(chuàng)建不同進程的.

兔寶寶 回答

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,
])

問題描述的真費勁啊

情已空 回答

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. 返回之前就立馬進行過濾.
    我之后準(zhǔn)備采用這個, https://github.com/yujunhao88...
    你可以參考下,不過這不是最終的,還在完善中

若相惜 回答

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

萌吟 回答
  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了。

朕略傻 回答

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

局外人 回答

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

來守候 回答

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

毀憶 回答

既然:

GRANT ALL PRIVILEGES ON PY4E.* TO 'root'@'localhost' IDENTIFIED BY 'pswd' WITH GRANT OPTION;

設(shè)置 passwordpswd
那么:

connection = pymysql.connect(host='127.0.0.1',
                             user='root',
                                 password='root',

這里的password就應(yīng)該是pswd, 而不是root.