主頁 > 資料庫 > DECIMAL 資料處理原理淺析

DECIMAL 資料處理原理淺析

2022-08-23 11:13:47 資料庫

注:本文分析內容基于 MySQL 8.0 版本

文章開始前先復習一下官方檔案關于 DECIMAL 型別的一些介紹:

The declaration syntax for a DECIMAL column is DECIMAL(M,D). The ranges of values for the arguments are as follows:

M is the maximum number of digits (the precision). It has a range of 1 to 65.

D is the number of digits to the right of the decimal point (the scale). It has a range of 0 to 30 and must be no larger than M.

If D is omitted, the default is 0. If M is omitted, the default is 10.

The maximum value of 65 for M means that calculations on DECIMAL values are accurate up to 65 digits. This limit of 65 digits of precision also applies to exact-value numeric literals, so the maximum range of such literals differs from before. (There is also a limit on how long the text of DECIMAL literals can be; see Section 12.25.3, “Expression Handling”.)

以上材料提到的最大精度和小數位是本文分析關注的重點:

  1. 最大精度是 65
  2. 小數位最多 30

接下來將先分析 MySQL 服務輸入處理 DECIMAL 型別的常數,

現在,先拋出幾個問題:

  1. MySQL 中當使用 SELECT 查詢常數時,例如:SELECT 123456789.123; 是如何處理的?
  2. MySQL 中查詢一下兩條陳述句分別回傳結果是多少?為什么?
    SELECT 111111111111111111111111111111111111111111111111111111111111111111111111111111111;
    SELECT 1111111111111111111111111111111111111111111111111111111111111111111111111111111111;
    

MySQL 如何決議常數

來看第1個問題,MySQL 的詞法分析在處理 SELECT 查詢常數的陳述句時,會根據數字串的長度選擇合適的型別來存盤數值,決策邏輯代碼位于 int_token(const char *str, uint length)@sql_lex.cc,具體的代碼片段如下:

static inline uint int_token(const char *str, uint length) {
  ...
  if (neg) {
      cmp = signed_long_str + 1;
      smaller = NUM;      // If <= signed_long_str
      bigger = LONG_NUM;  // If >= signed_long_str
    } else if (length < signed_longlong_len)
      return LONG_NUM;
    else if (length > signed_longlong_len)
      return DECIMAL_NUM;
    else {
      cmp = signed_longlong_str + 1;
      smaller = LONG_NUM;  // If <= signed_longlong_str
      bigger = DECIMAL_NUM;
    }
  } else {
    if (length == long_len) {
      cmp = long_str;
      smaller = NUM;
      bigger = LONG_NUM;
    } else if (length < longlong_len)
      return LONG_NUM;
    else if (length > longlong_len) {
      if (length > unsigned_longlong_len) return DECIMAL_NUM;
      cmp = unsigned_longlong_str;
      smaller = ULONGLONG_NUM;
      bigger = DECIMAL_NUM;
    } else {
      cmp = longlong_str;
      smaller = LONG_NUM;
      bigger = ULONGLONG_NUM;
    }
  }
  while (*cmp && *cmp++ == *str++)
    ;
  return ((uchar)str[-1] <= (uchar)cmp[-1]) ? smaller : bigger;
}

上面代碼中,long_len 值為 10longlong_len 值為 19unsigned_longlong_len值為20

neg表示是否是負數,直接看正數的處理分支,負數同理:

  • 當輸入的數值串長度等于 10 時 MySQL 可能使用 LONG_NUMLONG_NUM 表示
  • 當輸入的數值串長度小于 19 時 MySQL 使用 LONG_NUM 表示
  • 當輸入的數值串長度等于 20 時 MySQL 可能使用 LONG_NUMDECIMAL_NUM 表示
  • 當輸入的數值串長度大于 20 時 MySQL 使用 DECIMAL_NUM 表示
  • 其他長度時,MySQL 可能使用 LONG_NUMULONGLONG_NUM 表示

對于可能有兩種表示方式的資料,MySQL 是通過將數字串與 cmp 指向的數值字串進行比較,如果小于等于 cmp 表示的數值則使用 smaller 表示,否則使用 bigger 表示,cmp 指向的數值字串定義在 sql_lex.cc 檔案中,具體如下:

static const char *long_str = "2147483647";
static const uint long_len = 10;
static const char *signed_long_str = "-2147483648";
static const char *longlong_str = "9223372036854775807";
static const uint longlong_len = 19;
static const char *signed_longlong_str = "-9223372036854775808";
static const uint signed_longlong_len = 19;
static const char *unsigned_longlong_str = "18446744073709551615";
static const uint unsigned_longlong_len = 20;

因此,這里我們可以得出結論:MySQL 中當使用 SELECT 查詢常數時,根據數值串的長度和數值大小來決定使用什么型別來接收常數,當數值串長度大于 20,或數值串長度等于 20 且數值小于-9223372036854775808或大于18446744073709551615時,MySQL 服務選擇使用 DECIMAL 型別來接收處理常數,

這里,再拋出一個問題:
3. 上面分析提到的 DECIMAL 是否與官方檔案中提到的 DECIMAL 型別或者換一種方式說:是否與建表陳述句 CREATE TABLE t(d DECIMAL(65, 30)); 中欄位 dDECIMAL(65, 30)型別(可以不考慮精度和小數位)相同?

MySQL 決議 DECIMAL 常數時怎么處理溢位

分析第2個問題,先看一下陳述句的執行結果:

root@mysqldb 14:09:  [(none)]> SELECT 111111111111111111111111111111111111111111111111111111111111111111111111111111111;
+-----------------------------------------------------------------------------------+
| 111111111111111111111111111111111111111111111111111111111111111111111111111111111 |
+-----------------------------------------------------------------------------------+
| 111111111111111111111111111111111111111111111111111111111111111111111111111111111 |
+-----------------------------------------------------------------------------------+
1 row in set (2.28 sec)

root@mysqldb 14:09:  [(none)]> SELECT 1111111111111111111111111111111111111111111111111111111111111111111111111111111111;
+------------------------------------------------------------------------------------+
| 1111111111111111111111111111111111111111111111111111111111111111111111111111111111 |
+------------------------------------------------------------------------------------+
|                  99999999999999999999999999999999999999999999999999999999999999999 |
+------------------------------------------------------------------------------------+
1 row in set, 1 warning (2.01 sec)

接著上面的思路往下看常數的語法決議:

NUM_literal:
          int64_literal
        | DECIMAL_NUM
          {
            $$= NEW_PTN Item_decimal(@$, $1.str, $1.length, YYCSCL);
          }
        | FLOAT_NUM
          {
            $$= NEW_PTN Item_float(@$, $1.str, $1.length);
          }
        ;

語法決議器在獲取到 toekn = DECIMAL_NUM 后,會創建一個 Item_decimal 物件來存盤輸入的數值,

在分析代碼之前先來看幾個常數定義:

/** maximum length of buffer in our big digits (uint32). */
static constexpr int DECIMAL_BUFF_LENGTH{9};

/** the number of digits that my_decimal can possibly contain */
static constexpr int DECIMAL_MAX_POSSIBLE_PRECISION{DECIMAL_BUFF_LENGTH * 9};

/**
  maximum guaranteed precision of number in decimal digits (number of our
  digits * number of decimal digits in one our big digit - number of decimal
  digits in one our big digit decreased by 1 (because we always put decimal
  point on the border of our big digits))
*/
static constexpr int DECIMAL_MAX_PRECISION{DECIMAL_MAX_POSSIBLE_PRECISION -
                                           8 * 2};

static constexpr int DECIMAL_MAX_SCALE{30};
  • DECIMAL_BUFF_LENGTH:表示整個 DECIMAL 型別資料的緩沖區大小
  • DECIMAL_MAX_POSSIBLE_PRECISION:每個緩沖區單元可以存盤 9 位數字,所以最大可以處理的精度這里為 81
  • DECIMAL_MAX_PRECISION:用來限制官方檔案介紹中 decimal(M,D) 中的 M 的最大值,亦或是當超大常數溢位后回傳的整數部分最大長度
  • DECIMAL_MAX_SCALE:用來限制官方檔案介紹中 decimal(M,D) 中的 D 的最大值
Item_decimal::Item_decimal(const POS &pos, const char *str_arg, uint length,
                           const CHARSET_INFO *charset)
    : super(pos) {
  str2my_decimal(E_DEC_FATAL_ERROR, str_arg, length, charset, &decimal_value);
  item_name.set(str_arg);
  set_data_type(MYSQL_TYPE_NEWDECIMAL);
  decimals = (uint8)decimal_value.frac;
  fixed = true;
  max_length = my_decimal_precision_to_length_no_truncation(
      decimal_value.intg + decimals, decimals, unsigned_flag);
}

Item_decimal建構式中呼叫str2my_decimal函式對輸入數值進行處理,將其轉換為my_decimal型別的資料,

int str2my_decimal(uint mask, const char *from, size_t length,
                   const CHARSET_INFO *charset, my_decimal *decimal_value) {
  const char *end, *from_end;
  int err;
  char buff[STRING_BUFFER_USUAL_SIZE];
  String tmp(buff, sizeof(buff), &my_charset_bin);
  if (charset->mbminlen > 1) {
    uint dummy_errors;
    tmp.copy(from, length, charset, &my_charset_latin1, &dummy_errors);
    from = tmp.ptr();
    length = tmp.length();
    charset = &my_charset_bin;
  }
  from_end = end = from + length;
  err = string2decimal(from, (decimal_t *)decimal_value, &end);
  if (end != from_end && !err) {
    /* Give warning if there is something other than end space */
    for (; end < from_end; end++) {
      if (!my_isspace(&my_charset_latin1, *end)) {
        err = E_DEC_TRUNCATED;
        break;
      }
  }
  check_result_and_overflow(mask, err, decimal_value);
  return err;
}

str2my_decimal 函式先將數值字串轉為合適的字符集后,呼叫 string2decimal 函式將數值字串轉為 decimal_t 型別的資料,my_decimal 型別和 decimal_t 型別的關系如下:

@startuml

class decimal_t 
{
  + int intg, frac, len;
  + bool sign;
  + decimal_digit_t *buf;
}

class my_decimal
{
  - decimal_digit_t buffer[DECIMAL_BUFF_LENGTH];
}

decimal_t <|-- my_decimal
@enduml
  • decimal_digit_tint32_t 的別名
  • intg 表示整數部分的字符個數
  • frac 表示小數部分的字符個數
  • sign 表示是否負數
  • buf 指向 buffer
  • buffer 是資料存放陣列,陣列長度為9,也就意味著一個 decimal 最多可以存放 9int32_t 大小的資料,但由于設計限制每個陣列元素限制存盤 9 個字符,因此 buffer 最多可以存盤81個字符

由于 buffer 長度的限制,在 string2decimal 函式決議時會有溢位的可能,因此,決議后還需要呼叫check_result_and_overflow函式處理溢位的情況,

string2decimal 的代碼實作:

int string2decimal(const char *from, decimal_t *to, const char **end) {
  const char *s = from, *s1, *endp, *end_of_string = *end;
  int i, intg, frac, error, intg1, frac1;
  dec1 x, *buf;
  sanity(to);

  error = E_DEC_BAD_NUM; /* In case of bad number */
  while (s < end_of_string && my_isspace(&my_charset_latin1, *s)) s++;
  if (s == end_of_string) goto fatal_error;

  if ((to->sign = (*s == '-')))
    s++;
  else if (*s == '+')
    s++;

  s1 = s;
  while (s < end_of_string && my_isdigit(&my_charset_latin1, *s)) s++;
  intg = (int)(s - s1);
  if (s < end_of_string && *s == '.') {
    endp = s + 1;
    while (endp < end_of_string && my_isdigit(&my_charset_latin1, *endp))
      endp++;
    frac = (int)(endp - s - 1);
  } else {
    frac = 0;
    endp = s;
  }

  *end = endp;

  if (frac + intg == 0) goto fatal_error;

  error = 0;

  intg1 = ROUND_UP(intg);
  frac1 = ROUND_UP(frac);
  FIX_INTG_FRAC_ERROR(to->len, intg1, frac1, error);
  if (unlikely(error)) {
    frac = frac1 * DIG_PER_DEC1;
    if (error == E_DEC_OVERFLOW) intg = intg1 * DIG_PER_DEC1;
  }

  /* Error is guranteed to be set here */
  to->intg = intg;
  to->frac = frac;

  buf = to->buf + intg1;
  s1 = s;

  for (x = 0, i = 0; intg; intg--) {
    x += (*--s - '0') * powers10[i];

    if (unlikely(++i == DIG_PER_DEC1)) {
      *--buf = x;
      x = 0;
      i = 0;
    }
  }
  if (i) *--buf = x;

  buf = to->buf + intg1;
  for (x = 0, i = 0; frac; frac--) {
    x = (*++s1 - '0') + x * 10;

    if (unlikely(++i == DIG_PER_DEC1)) {
      *buf++ = x;
      x = 0;
      i = 0;
    }
  }
  if (i) *buf = x * powers10[DIG_PER_DEC1 - i];

  /* Handle exponent */
  if (endp + 1 < end_of_string && (*endp == 'e' || *endp == 'E')) {
    int str_error;
    longlong exponent = my_strtoll10(endp + 1, &end_of_string, &str_error);

    if (end_of_string != endp + 1) /* If at least one digit */
    {
      *end = end_of_string;
      if (str_error > 0) {
        error = E_DEC_BAD_NUM;
        goto fatal_error;
      }
      if (exponent > INT_MAX / 2 || (str_error == 0 && exponent < 0)) {
        error = E_DEC_OVERFLOW;
        goto fatal_error;
      }
      if (exponent < INT_MIN / 2 && error != E_DEC_OVERFLOW) {
        error = E_DEC_TRUNCATED;
        goto fatal_error;
      }
      if (error != E_DEC_OVERFLOW) error = decimal_shift(to, (int)exponent);
    }
  }
  /* Avoid returning negative zero, cfr. decimal_cmp() */
  if (to->sign && decimal_is_zero(to)) to->sign = false;
  return error;

fatal_error:
  decimal_make_zero(to);
  return error;
}

決議程序大致如下:

  1. 分別計算整數部分和小數部分各有多少個字符
  2. 分別計算整數部分和小數部分各需要多少個 buffer 元素來存盤
    1. 如果整數部分需要的 buffer 元素個數超過 9,則表示溢位
    2. 如果整數部分和小數部分需要的 buffer 元素個數超過 9,則表示需要將小數部分進行截斷
      由于先決議整數部分,再決議小數部分,因此,如果整數部分如果完全占用所有 buffer 元素,此時,小數部分會被截斷,
  3. 將整數部分和小數部分按每 9 個字符轉為一個整數記錄到 buffer 的元素中(buffer中的模型示例如下)
例如常數:111111111222222222333333333.444444444

intg = 27, frac = 9, len = 9, sign = false
byte         0            1           2           3          4         5         6         6         7         8
buffer: | 111111111 | 222222222 | 333333333 | 444444444 | UNKNOWN | UNKNOWN | UNKNOWN | UNKNOWN | UNKNOWN | UNKNOWN |
        低地址  -----------------------------------------------------------------------------------------------> 高地址

check_result_and_overflow 代碼實作:

void max_decimal(int precision, int frac, decimal_t *to) {
  int intpart;
  dec1 *buf = to->buf;
  assert(precision && precision >= frac);

  to->sign = false;
  // 發生溢位時將 buffer 中的資料更新為 9 99 999 ...
  if ((intpart = to->intg = (precision - frac))) {
    int firstdigits = intpart % DIG_PER_DEC1;
    if (firstdigits) *buf++ = powers10[firstdigits] - 1; /* get 9 99 999 ... */
    for (intpart /= DIG_PER_DEC1; intpart; intpart--) *buf++ = DIG_MAX;
  }

  if ((to->frac = frac)) {
    int lastdigits = frac % DIG_PER_DEC1;
    for (frac /= DIG_PER_DEC1; frac; frac--) *buf++ = DIG_MAX;
    if (lastdigits) *buf = frac_max[lastdigits - 1];
  }
}

inline void max_my_decimal(my_decimal *to, int precision, int frac) {
  assert((precision <= DECIMAL_MAX_PRECISION) && (frac <= DECIMAL_MAX_SCALE));
  max_decimal(precision, frac, to);
}

inline void max_internal_decimal(my_decimal *to) {
  max_my_decimal(to, DECIMAL_MAX_PRECISION, 0);
}

inline int check_result_and_overflow(uint mask, int result, my_decimal *val) {
  // 檢查前面的處理是否發生溢位
  if (val->check_result(mask, result) & E_DEC_OVERFLOW) {
    bool sign = val->sign();
    val->sanity_check();
    max_internal_decimal(val);
    val->sign(sign);
  }
  /*
    Avoid returning negative zero, cfr. decimal_cmp()
    For result == E_DEC_DIV_ZERO *val has not been assigned.
  */
  if (result != E_DEC_DIV_ZERO && val->sign() && decimal_is_zero(val))
    val->sign(false);
  return result;
}

如果 check_result_and_overflow 呼叫之前的處理發生了溢位行為,則意味著 decimal 不能存盤完整的資料,MySQL 決定這種情況下僅回傳decimal 默認的最大精度數值,由上面的代碼片段可以看出最大精度數值是 659

超大常量資料生成的 DECIMAL 資料與 DECIMAL 欄位型別的區別

通過上面對超大常量資料生成的 DECIMAL 資料處理的分析,可以得出問題3的答案:兩者不同,區別如下:

  1. DECIMAL 欄位型別有顯式的精度和小數位的限制,也就是 DECIMAL 欄位插入資料時能插入的正數部分的長度為 M-D,而超大常量資料生成的 DECIMAL 資料則會隱含的優先處理考慮整數部分,整數部分處理完才繼續處理小數部分,如果緩沖區不夠則將小數位截斷,如果緩沖區不夠整數部分存放則轉為 659
  2. 在 MySQL 的服務原始碼中 DECIMAL 欄位型別使用 Field_new_decimal 型別接收處理,而超大常量資料生成的 DECIMAL 資料由 Item_decimal 型別接收處理,

Enjoy GreatSQL ??

文章推薦:

有趣的SQL DIGEST

ulimits不生效導致資料庫啟動失敗和相關設定說明
MGR及GreatSQL資源匯總

GreatSQL MGR FAQ

在Linux下原始碼編譯安裝GreatSQL/MySQL

關于 GreatSQL

GreatSQL是由萬里資料庫維護的MySQL分支,專注于提升MGR可靠性及性能,支持InnoDB并行查詢特性,是適用于金融級應用的MySQL分支版本,

Gitee:
https://gitee.com/GreatSQL/GreatSQL

GitHub:
https://github.com/GreatSQL/GreatSQL

Bilibili:
https://space.bilibili.com/1363850082/favlist

技術交流群:

微信:掃碼添加GreatSQL社區助手微信好友,發送驗證資訊加群

圖片

轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/502529.html

標籤:其他

上一篇:DECIMAL 資料處理原理淺析

下一篇:StoneDB社區答疑第二期

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • GPU虛擬機創建時間深度優化

    **?桔妹導讀:**GPU虛擬機實體創建速度慢是公有云面臨的普遍問題,由于通常情況下創建虛擬機屬于低頻操作而未引起業界的重視,實際生產中還是存在對GPU實體創建時間有苛刻要求的業務場景。本文將介紹滴滴云在解決該問題時的思路、方法、并展示最終的優化成果。 從公有云服務商那里購買過虛擬主機的資深用戶,一 ......

    uj5u.com 2020-09-10 06:09:13 more
  • 可編程網卡芯片在滴滴云網路的應用實踐

    **?桔妹導讀:**隨著云規模不斷擴大以及業務層面對延遲、帶寬的要求越來越高,采用DPDK 加速網路報文處理的方式在橫向縱向擴展都出現了局限性。可編程芯片成為業界熱點。本文主要講述了可編程網卡芯片在滴滴云網路中的應用實踐,遇到的問題、帶來的收益以及開源社區貢獻。 #1. 資料中心面臨的問題 隨著滴滴 ......

    uj5u.com 2020-09-10 06:10:21 more
  • 滴滴資料通道服務演進之路

    **?桔妹導讀:**滴滴資料通道引擎承載著全公司的資料同步,為下游實時和離線場景提供了必不可少的源資料。隨著任務量的不斷增加,資料通道的整體架構也隨之發生改變。本文介紹了滴滴資料通道的發展歷程,遇到的問題以及今后的規劃。 #1. 背景 資料,對于任何一家互聯網公司來說都是非常重要的資產,公司的大資料 ......

    uj5u.com 2020-09-10 06:11:05 more
  • 滴滴AI Labs斬獲國際機器翻譯大賽中譯英方向世界第三

    **桔妹導讀:**深耕人工智能領域,致力于探索AI讓出行更美好的滴滴AI Labs再次斬獲國際大獎,這次獲獎的專案是什么呢?一起來看看詳細報道吧! 近日,由國際計算語言學協會ACL(The Association for Computational Linguistics)舉辦的世界最具影響力的機器 ......

    uj5u.com 2020-09-10 06:11:29 more
  • MPP (Massively Parallel Processing)大規模并行處理

    1、什么是mpp? MPP (Massively Parallel Processing),即大規模并行處理,在資料庫非共享集群中,每個節點都有獨立的磁盤存盤系統和記憶體系統,業務資料根據資料庫模型和應用特點劃分到各個節點上,每臺資料節點通過專用網路或者商業通用網路互相連接,彼此協同計算,作為整體提供 ......

    uj5u.com 2020-09-10 06:11:41 more
  • 滴滴資料倉庫指標體系建設實踐

    **桔妹導讀:**指標體系是什么?如何使用OSM模型和AARRR模型搭建指標體系?如何統一流程、規范化、工具化管理指標體系?本文會對建設的方法論結合滴滴資料指標體系建設實踐進行解答分析。 #1. 什么是指標體系 ##1.1 指標體系定義 指標體系是將零散單點的具有相互聯系的指標,系統化的組織起來,通 ......

    uj5u.com 2020-09-10 06:12:52 more
  • 單表千萬行資料庫 LIKE 搜索優化手記

    我們經常在資料庫中使用 LIKE 運算子來完成對資料的模糊搜索,LIKE 運算子用于在 WHERE 子句中搜索列中的指定模式。 如果需要查找客戶表中所有姓氏是“張”的資料,可以使用下面的 SQL 陳述句: SELECT * FROM Customer WHERE Name LIKE '張%' 如果需要 ......

    uj5u.com 2020-09-10 06:13:25 more
  • 滴滴Ceph分布式存盤系統優化之鎖優化

    **桔妹導讀:**Ceph是國際知名的開源分布式存盤系統,在工業界和學術界都有著重要的影響。Ceph的架構和演算法設計發表在國際系統領域頂級會議OSDI、SOSP、SC等上。Ceph社區得到Red Hat、SUSE、Intel等大公司的大力支持。Ceph是國際云計算領域應用最廣泛的開源分布式存盤系統, ......

    uj5u.com 2020-09-10 06:14:51 more
  • es~通過ElasticsearchTemplate進行聚合~嵌套聚合

    之前寫過《es~通過ElasticsearchTemplate進行聚合操作》的文章,這一次主要寫一個嵌套的聚合,例如先對sex集合,再對desc聚合,最后再對age求和,共三層嵌套。 Aggregations的部分特性類似于SQL語言中的group by,avg,sum等函式,Aggregation ......

    uj5u.com 2020-09-10 06:14:59 more
  • 爬蟲日志監控 -- Elastc Stack(ELK)部署

    傻瓜式部署,只需替換IP與用戶 導讀: 現ELK四大組件分別為:Elasticsearch(核心)、logstash(處理)、filebeat(采集)、kibana(可視化) 下載均在https://www.elastic.co/cn/downloads/下tar包,各組件版本最好一致,配合fdm會 ......

    uj5u.com 2020-09-10 06:15:05 more
最新发布
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:33:24 more
  • MySQL中binlog備份腳本分享

    關于MySQL的二進制日志(binlog),我們都知道二進制日志(binlog)非常重要,尤其當你需要point to point災難恢復的時侯,所以我們要對其進行備份。關于二進制日志(binlog)的備份,可以基于flush logs方式先切換binlog,然后拷貝&壓縮到到遠程服務器或本地服務器 ......

    uj5u.com 2023-04-20 08:28:06 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:27:27 more
  • 快取與資料庫雙寫一致性幾種策略分析

    本文將對幾種快取與資料庫保證資料一致性的使用方式進行分析。為保證高并發性能,以下分析場景不考慮執行的原子性及加鎖等強一致性要求的場景,僅追求最終一致性。 ......

    uj5u.com 2023-04-20 08:26:48 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:26:35 more
  • 云時代,MySQL到ClickHouse資料同步產品對比推薦

    ClickHouse 在執行分析查詢時的速度優勢很好的彌補了MySQL的不足,但是對于很多開發者和DBA來說,如何將MySQL穩定、高效、簡單的同步到 ClickHouse 卻很困難。本文對比了 NineData、MaterializeMySQL(ClickHouse自帶)、Bifrost 三款產品... ......

    uj5u.com 2023-04-20 08:26:29 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:25:13 more
  • Redis 報”OutOfDirectMemoryError“(堆外記憶體溢位)

    Redis 報錯“OutOfDirectMemoryError(堆外記憶體溢位) ”問題如下: 一、報錯資訊: 使用 Redis 的業務介面 ,產生 OutOfDirectMemoryError(堆外記憶體溢位),如圖: 格式化后的報錯資訊: { "timestamp": "2023-04-17 22: ......

    uj5u.com 2023-04-20 08:24:54 more
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:24:03 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:23:11 more