鍍金池/ 問答/ 數(shù)據(jù)庫問答
挽青絲 回答

我在微信群里也回答你了,先查一下Keepalive。參考這個Q&A:https://docs.mongodb.com/manu...

夢若殤 回答

間隙鎖是為了防止幻讀
MySQL InnoDB 鎖——官方文檔
https://segmentfault.com/a/11...

入她眼 回答

為什么數(shù)據(jù)庫查詢返回結(jié)果一定要符合你的格式要求呢?
這這個本身就是在你代碼業(yè)務(wù)層需要實現(xiàn)的功能啊!

六扇門 回答

你看下這樣行不行。
把input的value用數(shù)組表示,然后后臺接收到的所有input在一個數(shù)組中

$hotels = array();
$arr = $_POST['arr'];

foreach ($arr as $k => $v) {
    if($k%3 == 0){
        if($v){
            if(!$arr[$k+1] || !$arr[$k+2]){
                echo json_encode(array(
                    "code" => -1,
                    "msg"  => "如果填酒店名,就必須填金額,時間",
                ));
                die;
            }
            $hotels[] = array(
                "name" => $v,
                "cost" => $arr[$k+1],
                "time" => $arr[$k+2],
            );
        }else{
            $hotels[] = array(0, 0, 0);
        }
    }
}
echo json_encode(array(
    "code" => 0,
    "msg"  => "success",
));
幼梔 回答

mysqli:

<?php

$timezone="Asia/Shanghai";
date_default_timezone_set($timezone);

$host="localhost";
$db_user="sucaishui";//數(shù)據(jù)庫帳號
$db_pass="123456";//數(shù)據(jù)庫密碼
$db_name="xiaochengxu";//數(shù)據(jù)庫名

$db = new mysqli($host, $db_user, $db_pass, $db_name);
if ($db -> connect_errno) {
    error_log('[連接失敗][ ' . $db -> connect_error . ' ]');
}
$db -> query('SET NAMES utf8');

PDO:

<?php

$timezone="Asia/Shanghai";
date_default_timezone_set($timezone);

$host="localhost";
$db_user="sucaishui";//數(shù)據(jù)庫帳號
$db_pass="123456";//數(shù)據(jù)庫密碼
$db_name="xiaochengxu";//數(shù)據(jù)庫名

$dsn = "mysql:dbname={$db_name};host={$host}";

try {
    $db = new PDO($dsn, $db_user, $db_pass);
} catch (PDOException $e) {
    error_log('[連接失敗][ ' . $e -> getMessage() . ' ]');
}
$db -> exec('SET NAMES utf8');

大概是這樣?

臭榴蓮 回答

看場景:

  1. 日志是否需要實時分析?

如果不需要實時分析,可以用文件形式,固定格式存儲,然后進行離線分析。

  1. 是否一直都需要所有日志?

如果不需要所有日志,只需要部分日志,那么可以給一定時間之前的日志刪掉。

現(xiàn)在一般的做法都是,近期日志存在mongodb這種數(shù)據(jù)庫中,長期日志存儲在大數(shù)據(jù)平臺。

柚稚 回答

先看看update時有沒有deadlock異常,再看下事物,多少條commit一次,再用show processlist等操作看看數(shù)據(jù)庫執(zhí)行的sql狀況。

久愛她 回答

不要真的刪除Product記錄,而是添加一個bool型字段 isDelete 用于標(biāo)識產(chǎn)品是否是刪除的。

  1. 在展示產(chǎn)品列表時,過濾掉刪除的產(chǎn)品數(shù)據(jù)
  2. 在展示訂單時,不過濾刪除的產(chǎn)品。
喵小咪 回答

select * from t2 LEFT JOIN t1 ON t2. m_top_user_list like '%t1. user_id%'

呆萌傻 回答

其實這個問題可以看成是數(shù)學(xué)上集合的的問題
你的這個sql:

select * from user where name = 'A' or sex = '1' 

可以等價成下面這個sql

select * from user where name = 'A' AND sex = 1 
UNION ALL
SELECT * FROM user WHERE name = 'A' AND sex != 1
UNION ALL
SELECT * FROM user WHERE name != 'A' AND sex = 1

拆解成三部分,可以自由調(diào)整顯示順序
謝謝。

我以為 回答

set names utf8

設(shè)置一下編碼試試

萌小萌 回答

寫入數(shù)據(jù)和修改索引是在一個事務(wù)中完成。沒錯,雖然MongoDB從4.0才開始對外支持事務(wù),不過WiredTiger引擎從一開始就是支持內(nèi)部事務(wù)的。既然寫入數(shù)據(jù)時要同時更改索引,首先你必須要找到更改哪一部分索引。所以更新時也是需要查詢索引的。既然要查詢,索引必須到內(nèi)存中來。
所有WiredTiger緩存都是按照最近最少使用(LRU)的原則來清除的,無論是不是索引。使用得頻繁就有更大的機會駐留內(nèi)存。
最后一個問題,沒有這么簡單的計算方法。索引本質(zhì)上是鍵值對。值占用的空間都一樣,但鍵的大小不一樣。而且索引鍵還會壓縮,很難估計最后的實際大小。最簡單的辦法,根據(jù)你的要求自己模擬一批數(shù)據(jù),然后查看db.<集合>.stats(),里面會有索引大小。然后根據(jù)你的數(shù)據(jù)數(shù)量和索引大小大概估算下達到實際數(shù)據(jù)量時索引有多大。這個大小也大致是需要占用的內(nèi)存大小。

尐懶貓 回答

下次記得把原始查詢也發(fā)出來,我們看著更方便些。從執(zhí)行計劃來反推,查詢大約是

db.webDevice.find({
    lid: {
        $in: [
            "40CnwyHkVmnA9kbScMLNLneaxuS4Tcj",
            "140CnwyHkVmnA9kbScMLNLneaxuS4Tcj"
        ]
    }
}).sort({createTime: -1}).limit(1);

因為命中索引,這個查詢獲取數(shù)據(jù)的速度實際上比較快,你也提到在一段時間內(nèi)第二次查詢就快了,這是一個很明顯的特點,代表內(nèi)存不足。MongoDB和其他數(shù)據(jù)庫一樣,都會使用空閑內(nèi)存緩沖索引和數(shù)據(jù),當(dāng)內(nèi)存不足時就會使用LRU算法清理舊數(shù)據(jù)換入新數(shù)據(jù)再繼續(xù)查詢。因為這個過程涉及到磁盤數(shù)據(jù)交換,速度會大大降低。發(fā)生這種情況有一個特點,就是一段時間內(nèi)第二次執(zhí)行時速度就快了(因為數(shù)據(jù)已經(jīng)在內(nèi)存中)。但是如果過一段時間再執(zhí)行,速度又會變慢(因為又被換出內(nèi)存了)。所以你的情況實際上就是受限于硬件。
既然如此最直接的解決辦法就是:

  1. 使用更快的硬盤;
  2. 使用更大的內(nèi)存;

如果不能從硬件方面解決,有一點可以嘗試就是用CPU換內(nèi)存。做法是盡可能調(diào)小cacheSizeGB(是的沒錯,是調(diào)?。?。空閑出來的內(nèi)存操作系統(tǒng)會用來緩沖磁盤數(shù)據(jù),而磁盤數(shù)據(jù)是經(jīng)過壓縮的,體積更小,因此可以緩沖更多數(shù)據(jù)到內(nèi)存中。但作為交換,在使用這些數(shù)據(jù)時需要經(jīng)過CPU再進行一次解壓從而額外消耗CPU。即使這樣,效果也比從磁盤讀取要好很多。整個過程是自動進行的,你需要做的只是調(diào)小cacheSizeGB。
這種做法可以在一定程度上緩解內(nèi)存不足的問題,但不是萬能的:

  • 首先它會增加CPU消耗,如果你的系統(tǒng)本身已經(jīng)沒有剩余的CPU資源,這種做法就不合適;
  • 其次受制于壓縮率,這樣做之后內(nèi)存能容納的數(shù)據(jù)并不會比以前多很多,所以并不是萬能的;

補充回答

基于你的新的疑問,以下幾點補充:

疑問1: 按照你說的方式調(diào)小cacheSizeGB,應(yīng)該怎么調(diào)整比較合理

我在上面有提到,這樣做的效果有限,是受制于壓縮率的限制。所以多容納的數(shù)據(jù)實際就是壓縮的數(shù)據(jù)。比如1G的內(nèi)存能放多少數(shù)據(jù)?

  • 如果不壓縮(壓縮率100%),1G內(nèi)存能放1GB數(shù)據(jù);
  • 如果壓縮率90%,1G內(nèi)存可以放10/9GB~=1.11數(shù)據(jù);
  • 如果壓縮率80%,1G內(nèi)存可以放10/8 = 1.25GB數(shù)據(jù);
  • 以此類推……

所以調(diào)到多少,其實要看你想往內(nèi)存里放多少數(shù)據(jù),而這往往是一個不確定的數(shù)值。這里會有另外一個概念叫做工作集(working set),就是你經(jīng)常用到的那些數(shù)據(jù)。比如你的數(shù)據(jù)庫共有100GB數(shù)據(jù),但是你經(jīng)常用到的部分只有10GB,那么你的內(nèi)存只要能裝下10GB數(shù)據(jù),應(yīng)用在大部分時候就可以非??欤O碌那闆r忽略就好了。
基于上面這些分析,你應(yīng)該可以算一下,你的工作集有多大,數(shù)據(jù)壓縮率有多大,那么需要把cacheSizeGB調(diào)到多小才能容納下工作集(又或者調(diào)到多小都不可能容納下工作集)。你的情況是內(nèi)存不足CPU空閑,所以如果懶得算,直接把cacheSizeGB調(diào)到最小值就好了。

疑問2: config只用了1.5GB內(nèi)存(限制了CacheSizeGB3GB).可以說明索引都加載到了內(nèi)存中嗎?

這說明config數(shù)據(jù)庫(元數(shù)據(jù))的索引和數(shù)據(jù)都加載到內(nèi)存中了。注意數(shù)據(jù)的索引肯定是在shard中,與config無關(guān)。而且大頭是在shard上面。
順便提一下,如果不是實驗?zāi)康?,根本沒必要分這么多片。因為在一臺機器上分再多片,硬件資源也只有這么多,對于性能沒有什么意義,反而還會有額外的傳輸開銷。

疑問3: mongodb remove數(shù)據(jù)后,查詢卻越來越慢是什么情況?

remove之后跟查詢沒有本質(zhì)上的聯(lián)系,可能只是湊巧發(fā)生在一起。如果你有足夠的證據(jù)覺得這兩者確實有聯(lián)系,請另開問題描述清楚問題的上下文以及你發(fā)現(xiàn)的情況,必要的時候也可以求助于MongoDB JIRA。如果一定要做一個無根據(jù)的猜測,我覺得可能是remove時導(dǎo)致熱數(shù)據(jù)被換出內(nèi)存(注意remove也需要先找到滿足條件的數(shù)據(jù)然后才能刪除),引起后面的查詢需要重新從磁盤上加載數(shù)據(jù)造成的。

赱丅呿 回答

1.數(shù)據(jù)庫字段類型約束 選用無符號類型

2.程序代碼去約束

3.錄入價格的時候效驗

陌顏 回答

目錄放一張表就行了
id name bookid acticleid pid
一級目錄pid為0 二級目錄pid為一級目錄的id

另外mysql字段類型占用大小
https://dev.mysql.com/doc/ref...
直接看看文檔吧

綰青絲 回答

點最后一個按鈕

別傷我 回答

RR在讀取數(shù)據(jù),事務(wù)開啟的時候,不允許修改操作??梢越鉀Q不可重復(fù)讀的問題,但是還是不能根本解決幻讀問題。幻讀對應(yīng)的應(yīng)該是insert操作。RR針對的是update操作。

不將就 回答

你可以先把fetch的結(jié)果保存到數(shù)組中然后再用數(shù)組來循環(huán)。

$rows=array();
while($row=mysqli_fetch_array($result)) {
$rows[]=$row;
}

foreach($rows as $row) {
A
}

foreach($rows as $row) {
B
}

或者干脆用mysqli_fetch_all,據(jù)說性能上有些許優(yōu)勢:

$rows=mysqli_fetch_all($result, MYSQLI_BOTH);

注意mysqli_fetch_all默認(rèn)是MYSQLI_NUM,和mysqli_fetch_array不一樣,所以要加第二個參數(shù)。

嫑吢丕 回答
--testtable

delimiter //
create trigger insertTrigger before insert on testtable
for each row set new.w = new.a + new.b + new.c + new.d;
//

create trigger updateTrigger before update on testtable
for each row set new.w = new.a + new.b + new.c + new.d;
//

delimiter ;
乞許 回答

一般來說就是把前后端解耦,前端一套可以部署到靜態(tài)服務(wù)器獨立跑,需要數(shù)據(jù)時再AJAX訪問后端提供的相應(yīng)接口拿東西。