ホームページ  >  記事  >  データベース  >  [MySQL] MySQL データ型の最適化

[MySQL] MySQL データ型の最適化

黄舟
黄舟オリジナル
2017-02-25 10:19:591086ブラウズ

最適化されたデータ型を選択する

MySQL は多くのデータ型をサポートしており、高いパフォーマンスを達成するには適切なデータ型を選択することが重要です。保存するデータの種類に関係なく、より良い選択をするために役立ついくつかの原則を以下に示します。

通常は小さいほど良いです

一般に、データを正しく格納できる最小のデータ型を使用するようにしてください (たとえば、0 ~ 200 のみを格納する必要があり、tinyint unsigned の方が優れています)。データ型が小さいほど、占有するディスク、メモリ、CPU キャッシュが少なくなり、処理に必要な CPU サイクルが少なくなるため、一般に高速になります。

シンプルであることは良いことです

単純なデータ型の操作では、通常、必要な CPU サイクルが少なくなります。たとえば、文字セットと照合順序 (照合順序) により文字列比較が整数比較よりも複雑になるため、整数演算は文字演算よりもコストが低くなります。ここでは 2 つの例を示します。1 つは、日付と時刻を格納するために文字列の代わりに MySQL の組み込み型 (日付、時刻、日付時刻など) を使用する必要があるということ、もう 1 つは IP アドレスを格納するために整数を使用する必要があるということです。

NULL の使用は避けてください

アプリケーションで NULL を保存する必要がない場合でも、多くのテーブルには NULL 許容カラムが含まれています。これは、NULL 可能性がカラムのデフォルト属性であるためです。本当に NULL 値を格納する必要がない限り、通常は列を NOT NULL として指定するのが最善です。

クエリに NULL 許容カラムが含まれている場合、NULL 許容カラムによりインデックス、インデックス統計、および値の比較がより複雑になるため、MySQL の最適化がより困難になります。 NULL にできるカラムはより多くのストレージ領域を使用するため、MySQL での特別な処理が必要になります。 NULL 許容カラムにインデックスが付けられると、各インデックス レコードに余分なバイトが必要になります。これにより、MyISAM では、固定サイズのインデックス (整数カラムが 1 つだけあるインデックスなど) が可変サイズのインデックスになることもあります。

通常、NULL 値を NOT NULL に変更することによってもたらされるパフォーマンスの向上は比較的小さいため、(チューニング時に) 問題が発生すると判断されない限り、既存のスキーマでこの状況を最初に見つけて変更する必要はありません。ただし、列にインデックスを作成する予定がある場合は、列を NULL 許容になるように設計することは避けてください。

もちろん例外もあります。たとえば、InnoDB は NULL 値を格納するために別のビットを使用するため、スパース データに対して優れたスペース効率を備えていることに注意してください (ほとんどの値は NULL であり、一部の行のみが非値です)。 NULL 値)。ただし、これは MyISAM には当てはまりません。


整数型

整数を保存する場合は、TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT の整数型を使用できます。それぞれ 8、16、24、32、および 64 ビットのストレージ領域を使用します。それらの記憶範囲は、-2 の (N-1) 乗から 2 の (N-1) -1 乗までです。ここで、N は記憶空間内のビット数です。

整数型にはオプションの UNSIGNED 属性があります。これは、負の値が許可されないことを意味します。これにより、たとえば、TINYINT UNSIGNED の格納範囲は 0 ~ 255 になります。 TINYINT の範囲は -128 ~ 127 です。

MySQL は、INT(11) などの整数型の幅を指定できますが、これはほとんどのアプリケーションにとっては無意味です。これは、値の法定範囲を制限するものではなく、MySQL のいくつかの対話型ツール (MySQL コマンド ラインなど) についての知識が規定されています。 client) 文字数を表示するために使用されます。ストレージの場合、INT(1) と INT(20) は同じです。

実数型

実数とは、小数部を持つ数値です。ただし、DECIMAL は小数部分を格納するためだけでなく、BIGINT より大きい整数を格納するためにも使用できます。 MySQL は、正確な型と不正確な型の両方をサポートします。

FLOAT 型と DOUBLE 型は、標準の浮動小数点演算を使用した近似計算をサポートします。浮動小数点演算がどのように計算されるかを知る必要がある場合は、使用しているプラ​​ットフォームでの浮動小数点数の具体的な実装を調べる必要があります。

DECIMAL 型は、正確な小数を格納するために使用されます。ただし、CPU が DECIMAL の直接計算をサポートしていないため、MySQL5.0 以降のバージョンでは、MySQL サーバー自体が DECIMAL の高精度計算を実装します。相対的に言えば、これはネイティブ浮動小数点演算を直接サポートする CPU よりも遅くなります。

浮動小数点型とDECIMAL型の両方で精度を指定できます。 DECIMAL 列の場合、小数点の前後に許可される最大桁数を指定できます。これは列のスペース消費に影響します。

同じ範囲の値を格納する場合、浮動小数点型は通常、DECIMAL よりも使用するスペースが少なくなります。 FLOAT は 4 バイトのストレージを使用します。 DOUBLE は 8 バイトを占有し、FLOAT よりも精度が高く、範囲も広くなります。

追加のスペースと計算オーバーヘッドが必要なため、財務データの保存など、小数に関する正確な計算を実行する場合は DECIMAL のみを使用するようにしてください。ただし、データ量が比較的大きい場合は、DECIMAL の代わりに BIGINT を使用し、格納する通貨単位を小数点以下の桁数に応じた倍数で乗算することを検討できます。財務データを 10,000 分の 1 まで正確に保存したい場合は、すべての金額を 100 万で乗算し、その結果を BIGINT に保存することで、不正確な浮動小数点ストレージ計算や正確な DECIMAL 計算の高コストの問題を回避できます。

String型

以下の説明は、使用されるストレージエンジンがInnoDB/またはMyISAMであることを前提としています。これら 2 つのストレージ エンジンでサポートされていない場合は、使用するストレージ エンジンのドキュメントを参照してください。

VARCHAR および CHAR

VARCHAR: 必要なスペースのみを使用するため、固定長型よりもスペース効率が高くなります。 VARCHAR はスペースを節約するため、パフォーマンスも向上します。ただし、行の長さは可変であるため、UPDATE 中に行が元の行より長くなる可能性があり、追加の作業が必要になります。

次の状況では VARCHAR を使用するのが適切です: 文字列の最大長が平均の長さよりもはるかに長い場合、列の更新が少ないため、UTF-8 のような複雑な文字セットが使用されている場合。 、各文字は異なる文字セクション番号を使用します。

バージョン 5.0 以降では、MySQL は保存および取得時に末尾のスペースを保持します。 InnoDB はより柔軟で、長い VARCHAR を BLOB

CHAR として保存できます。CHAR 値を保存するとき、MySQL は末尾のスペースをすべて削除します。固定長 CHAR 型は断片化が起こりにくく、非常に短い列の場合、レコード長が 1 バイトまたは 2 バイト余分にある VARCHAR よりも CHAR の方が記憶領域の効率が高くなります。 CHAR は、非常に短い文字列を格納する場合、またはすべての値が同じ長さに近い場合に適しています。例: CHAR は固定長値であるため、パスワードの MD5 値を格納するのに非常に適しています。比較を容易にするために、CHAR には必要に応じてスペースが埋め込まれます。

CHAR と VARCHAR に似た型は、バイナリ文字列を格納する BINARY と VARBINARY です。バイナリ文字列には、文字ではなくバイトコードが格納されます。

バイナリ比較の利点は、大文字と小文字を区別することだけではありません。 MySQL は、BINARY 文字列を一度に 1 バイトずつ比較し、バイトの値に基づいて比較します。したがって、バイナリは文字よりもはるかに単純であるため、高速です。

BLOB 型と TEXT 型

BLOB 型と TEXT 型: BLOB と TEXT は両方とも大きなデータを格納するように設計された文字列データ型で、それぞれバイナリ モードと文字モードで格納されます。 BLOB 値と TEXT 値が大きすぎる場合、InnoDB はストレージに専用の「外部」ストレージ領域を使用します。元のテーブル フィールドのストレージ ポインターは、外部ストレージ領域を指します。

MySQL は BLOB 列と TEXT 列を他のタイプとは異なる方法でソートします。最初に列のみをソートしますmax_sort_length 字节而不是整个字符串做排序。如果只需要排序前面一小部分字符,则可以减小max_sort_length 的配置,或者使用ORDER BY SUSTRING(column, length)

MySQL は、BLOB 列と TEXT 列の完全な長さの文字列にインデックスを付けることはできません。また、これらのインデックスを使用して並べ替えを排除することもできません。

文字列型の代わりに列挙型 (ENUM) を使用します

文字列型の代わりに列挙型 (ENUM) を使用できます。多くの場合、一般的に使用される文字列型の代わりに列挙列を使用することが推奨されます。

(1) 列挙列は、事前定義されたコレクションにいくつかの一意の文字列を格納できます。
(2) Mysql は列挙型を格納する際に非常にコンパクトであり、リスト値の数に応じて 1 バイトまたは 2 バイトに圧縮されます。
(3) MySQL は内部的にリスト内の各値の位置を整数として保存し、「数値と文字列」のマッピング関係の「ルックアップ テーブル」をテーブルの .frm ファイルに保存します。

注: 驚くべきことの 1 つは、列挙型フィールドが、定義された文字列ではなく内部的に保存された整数によって並べ替えられることです。

注: 列挙型の最悪の点は、文字列の追加または削除には ALTER TABLE を使用する必要があるため、将来変更される可能性がある場合を除き、列挙型を使用することはお勧めできません。要素はリストの最後にのみ追加できることが認められています。

注: Mysql は各列挙値を整数として保存し、文字列に変換するために検索を行う必要があるため、列挙型列にはある程度のオーバーヘッドが発生します。

日時型

データ型と使用法の詳細については、http://www.php.cn/

Mysql には、YEAR や DATE など、日付と時刻の値を保存できる多くの型があります。

Mysql が保存できる最小時間粒度は秒です (MariaDB はマイクロ秒レベルのイベント タイプをサポートします)。ただし、MySQL はマイクロ秒レベルの粒度でアドホック操作を実行することもできます。

ほとんどの場合、そのタイプに代わるものはないため、何が最善の選択であるかについては疑問の余地はありません。

次の唯一の問題は、日付と時刻を保存するときに何をする必要があるかです。

DATETIME

(1) この型は、1001 から 9999 までの幅広い値を秒の精度で保存できます。 (2) DATETIME は、タイム ゾーンに関係なく、時刻と日付を YYYYMMDDHHMMSS 形式の整数にカプセル化します。 (3) DATETIME は 8 バイトの記憶領域を使用します。

TIMESTAMP

(1) TIMESTAMP 型には、1970 年 1 月 1 日の午前 0 時からの秒数が格納されます。これは、UNIX タイムスタンプと同じです。 (2) TIMESTAMP は 4 バイトの記憶領域しか使用しないため、その範囲は DATETIME よりもはるかに小さくなります。 (3) TIMESTAMPで表示される値はタイムゾーンによって異なります。

DATETIME と TIMESTAMP の比較:

(1) デフォルトでは、挿入時に最初の TIMESTAMP カラムの値が指定されていない場合、Mysql はこのカラムの値を現在時刻に設定します。 (これは DATETIME にはない機能です) (2) レコードの行を挿入すると、Mysql はデフォルトで最初の TIMESTAMP カラムの値も更新します。 (3) TIMESTAMP 列のデフォルトは NOT NULL であり、他のデータ型とは異なります。

概要

(1) 特殊な動作に加えて、DATETIME よりもスペース効率が高いため、一般に TIMESTAMP を可能な限り使用する必要があります。 (2) 一般に、UNIX タイムスタンプを整数値として保存することはお勧めできません。整数値でタイムスタンプ形式を保存しても、通常は処理に不便です。 (3) 秒よりも小さい粒度で日付と時刻の値を保存する必要がある場合は、BIGINT 型を使用してマイクロ秒レベルのタイムスタンプを保存するか、DOUBLE を使用して秒以降の小数部分を保存することもできます。 MySQLの代わりに。

ビット データ型

MySQL には、データを保存するためにコンパクト ビットを使用するストレージ タイプがいくつかあります。これらのビット型はすべて、基礎となるストレージ形式や処理に関係なく、技術的には文字列型です。

BIT

BIT 列を使用して、1 つ以上の true/false 値を列に格納できます。 BIT(1) は単一ビットを含むフィールドを定義し、BIT(2) は 2 ビットを格納します。 BIT 列の最大長は 64 ビットです。

true/false 値を少しの記憶領域に保存したい場合は、NULL にできる CHAR(0) 列を作成するという別の方法もあります。この列には、NULL 値 (NULL) または長さ 0 の文字列 (空の文字列) を保持できます。

SET

多くの true/false 値を保存する必要がある場合は、これらの列を SET データ型にマージすることを検討できます。SET データ型は、MySQL によって内部的にパックされたビットのセットとして表されます。これによりストレージ領域が効率的に利用され、MySQL にはクエリで簡単に使用できる FIND_IN_SET() や FIELD() などの関数が備わっています。その主な欠点は、列定義の変更にコストがかかることです。ALTER TABLE が必要ですが、これは大きなテーブルの場合は非常にコストのかかる操作です。一般に、SET 列のインデックスを検索することもできません。

SET の代わりに、整数を使用して一連のビットをラップすることもできます。たとえば、8 ビットを TINYINT にパックし、ビット単位の演算で使用できます。アプリケーションの各ビットに名前付き定数を定義することで、これを簡素化できます。

SET と比較した場合、このメソッドの主な利点は、ALTER TABLE を使用せずにフィールドで表される「列挙」値を変更できることです。欠点は、クエリ ステートメントの記述がより難しく、理解しにくいことです。 5 番目のビットが設定されています。どういう意味ですか?)。このアプローチに非常に慣れている人もいれば、そうでない人もいるので、このテクニックを採用するかどうかは個人の好みによって決まります。

識別子 (識別子) を選択します

識別子 (識別列) に適切なデータ型を選択することが非常に重要です。

一般に、ID 列を使用して他の値と比較したり、ID 列を通じて他の列を検索したりする可能性が高くなります。

ID 列のタイプを選択するときは、ストレージ タイプだけでなく、Mysql がこのタイプに対して計算と比較を実行する方法も考慮する必要があります。

タイプを選択したら、関連するすべてのテーブルで必ず同じタイプを使用してください。

値の範囲要件が満たされ、将来の拡張の余地が確保されていることを前提として、最小のデータ型を選択する必要があります。

  • 通常、整数は高速であり、AUTO_INCREMENT で使用できるため、ID 列には最適な選択です。 AUTO_INCREMENT

  • ENUM和SET是最糟糕的选择了;

  • 如果可能也尽可能避免使用字符串作为标识列,因为它们很消耗空间并且通常比数字类慢。

特殊类型数据

某些类型的数据并不直接与内置类型一致。低于秒级精度的时间戳就是一个例子。

另一个例子是人们通常使用VARCHAR(15)来存储IP地址。然而,它们实际是32位无符号整数,不是字符串。用小数点将字段分割成四段是为了阅读方便。所以应该用无符号整数存储IP地址。MySQL提供INET_ATON()INET_NTOA()

ENUM と SET は最悪の選択です。

また、スペースを消費し、通常は数値型よりも遅いため、文字列を ID 列として使用することはできるだけ避けてください。

特殊なタイプのデータ

一部のタイプのデータは、組み込みタイプと直接一致しません。 1 秒未満の精度のタイムスタンプは一例です。

もう 1 つの例は、IP アドレスを保存するために通常 VARCHAR(15) を使用することです。ただし、実際には文字列ではなく、32 ビットの符号なし整数です。読みやすくするために、フィールドを小数点を使用して 4 つのセグメントに分割しています。したがって、IP アドレスは符号なし整数として保存する必要があります。 MySQL は、これら 2 つの表現方法の間で変換するための INET_ATON() 関数と INET_NTOA() 関数を提供します。

最適化されたデータ型を選択する

MySQL は多くのデータ型をサポートしており、高いパフォーマンスを達成するには適切なデータ型を選択することが重要です。保存するデータの種類に関係なく、より良い選択をするために役立ついくつかの原則を以下に示します。

通常は小さいほど良いです🎜🎜 一般に、データを正しく格納できる最小のデータ型を使用するようにしてください (たとえば、0 ~ 200 のみを格納する必要があり、tinyint unsigned の方が優れています)。データ型が小さいほど、占有するディスク、メモリ、CPU キャッシュが少なくなり、処理に必要な CPU サイクルが少なくなるため、一般に高速になります。 🎜🎜シンプルであることは良いことです🎜🎜単純なデータ型の操作では、通常、必要な CPU サイクルが少なくなります。たとえば、文字セットと照合順序 (照合順序) により文字列比較が整数比較よりも複雑になるため、整数演算は文字演算よりもコストが低くなります。ここでは 2 つの例を示します。1 つは、日付と時刻を格納するために文字列の代わりに MySQL の組み込み型 (日付、時刻、日付時刻など) を使用する必要があるということ、もう 1 つは IP アドレスを格納するために整数を使用する必要があるということです。 🎜🎜NULL の使用は避けてください🎜🎜 アプリケーションで NULL を保存する必要がない場合でも、多くのテーブルには NULL 許容カラムが含まれています。これは、NULL 可能性がカラムのデフォルト属性であるためです。本当に NULL 値を格納する必要がない限り、通常は列を NOT NULL として指定するのが最善です。 🎜

如果查询中包含可为NULL的列,对MySQL来说更难优化,因为可为NULL的列使得索引、索引统计和值比较都更复杂。可为NULL的列会使用更多的存储空间,在MySQL里也需要特殊处理。当可为NULL的列被索引时,每个索引记录需要一个额外的字节,在MyISAM中甚至还可能导致固定大小的索引(例如只有一个整数列的索引)变成可变大小的索引。

通常把可为NULL的值改为NOT NULL带来的性能提升比较小,所以(调优时)没有必要首先在现有的schema中查找并修改掉这种情况,除非确定这会导致问题。但是,如果计划在列上建立索引,就应该避免设计成可为NULL的列。

当然也有例外,例如值得一提的是,InnoDB使用单独的位(bit)存储NULL值,所以对于稀疏数据(大部分值为NULL,只有少数行为非NULL的值)有良好的空间效率。但这一点不适用于MyISAM。


整数类型

如果存储整数,可以使用这几种整数类型:TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT。分别使用8,16,24,32,64位存储空间。它们的存储范围从 -2的(N-1)次方 到 2的(N-1)次方-1,其中N为存储空间的位数。

整数类型有可选的UNSIGNED属性,表示不允许负值,这大致可以使正数的上限提高一倍,例如TINYINT UNSIGNED可以存储的范围是0-255,而TINYINT 的存储范围是-128~127。

MySQL可以为整数类型指定宽度,例如INT(11),对大多数应用这是没有意义的:他不会限制值得合法范围,知识规定了MySQL的一些交互工具(例如MySQL命令行客户端)用来显示字符的个数。对于存储来说,INT(1)和INT(20)是相同的。

实数类型

实数是带有小数部分的数字。然而,它们不只是为了存储小数部分,也可以使用DECIMAL存储比BIGINT还大的整数。MySQL既支持精确类型,也支持不精确类型。

FLOAT 和 DOUBLE 类型支持使用标准的浮点运算进行近似计算。如果需要知道浮点运算时怎么计算的,则需要研究所使用的平台的浮点数的具体实现。

DECIMAL 类型用于存储精确的小数。但因为CPU不支持对DECIMAL的直接计算,所以在MySQL5.0及更高版本中,MySQL服务器自身实现了DECIMAL的高精度计算。相对而言,这比CPU直接支持原生浮点数运算要慢。

浮点和DECIMAL类型都可以指定精度。对于DECIMAL列,可以指定小数点前后所允许的最大位数。这会影响列的空间消耗。

浮点类型在存储同样范围的值时,通常比DECIMAL使用更少的空间。FLOAT使用4个字节存储。DOUBLE占用8个字节,相比FLOAT有更高的精度和更大的范围。

因为需要额外的空间和计算开销,所以应该尽量只在对小数进行精确计算时才使用DECIMAL——例如存储财务数据。但数据量比较大的时候,可以考虑使用BIGINT代替DECIMAL,将需要存储的货币单位根据小数点的位数乘以相应的倍数即可。假设要存储财务数据精确到万分之一分,则可以把所有金额乘以100W,然后将结果存储在BIGINT里,这样可以同时避免浮点存储计算不精确和DECIMAL精确计算代价高的问题。

字符串类型

下面的描述假设使用的存储引擎是InnoDB/或者MyISAM。如果不是这两种存储引擎的,请参考所使用的存储引擎的文档。

VARCHAR および CHAR

VARCHAR: 必要なスペースのみを使用するため、固定長型よりもスペース効率が高くなります。 VARCHAR はスペースを節約するため、パフォーマンスも向上します。ただし、行の長さは可変であるため、UPDATE 中に行が元の行より長くなる可能性があり、追加の作業が必要になります。

次の状況では VARCHAR を使用するのが適切です: 文字列の最大長が平均の長さよりもはるかに長い場合、列の更新が少ないため、UTF-8 のような複雑な文字セットが使用されている場合。 、各文字は異なる文字セクション番号を使用します。

バージョン 5.0 以降では、MySQL は保存および取得時に末尾のスペースを保持します。 InnoDB はより柔軟で、長い VARCHAR を BLOB

CHAR として保存できます。CHAR 値を保存するとき、MySQL は末尾のスペースをすべて削除します。固定長 CHAR 型は断片化が起こりにくく、非常に短い列の場合、レコード長が 1 バイトまたは 2 バイト余分にある VARCHAR よりも CHAR の方が記憶領域の効率が高くなります。 CHAR は、非常に短い文字列を格納する場合、またはすべての値が同じ長さに近い場合に適しています。例: CHAR は固定長値であるため、パスワードの MD5 値を格納するのに非常に適しています。比較を容易にするために、CHAR には必要に応じてスペースが埋め込まれます。

CHAR と VARCHAR に似た型は、バイナリ文字列を格納する BINARY と VARBINARY です。バイナリ文字列には、文字ではなくバイトコードが格納されます。

バイナリ比較の利点は、大文字と小文字を区別することだけではありません。 MySQL は、BINARY 文字列を一度に 1 バイトずつ比較し、バイトの値に基づいて比較します。したがって、バイナリは文字よりもはるかに単純であるため、高速です。

BLOB 型と TEXT 型

BLOB 型と TEXT 型: BLOB と TEXT は両方とも大きなデータを格納するように設計された文字列データ型で、それぞれバイナリ モードと文字モードで格納されます。 BLOB 値と TEXT 値が大きすぎる場合、InnoDB はストレージに専用の「外部」ストレージ領域を使用します。元のテーブル フィールドのストレージ ポインターは、外部ストレージ領域を指します。

MySQL は BLOB 列と TEXT 列を他のタイプとは異なる方法でソートします。最初に列のみをソートしますmax_sort_length 字节而不是整个字符串做排序。如果只需要排序前面一小部分字符,则可以减小max_sort_length 的配置,或者使用ORDER BY SUSTRING(column, length)

MySQL は、BLOB 列と TEXT 列の完全な長さの文字列にインデックスを付けることはできません。また、これらのインデックスを使用して並べ替えを排除することもできません。

文字列型の代わりに列挙型 (ENUM) を使用します

文字列型の代わりに列挙型 (ENUM) を使用できます。多くの場合、一般的に使用される文字列型の代わりに列挙列を使用することが推奨されます。

(1) 列挙列は、事前定義されたコレクションにいくつかの一意の文字列を格納できます。
(2) Mysql は列挙型を格納する際に非常にコンパクトであり、リスト値の数に応じて 1 バイトまたは 2 バイトに圧縮されます。
(3) MySQL は内部的にリスト内の各値の位置を整数として保存し、「数値と文字列」のマッピング関係の「ルックアップ テーブル」をテーブルの .frm ファイルに保存します。

注: 驚くべきことの 1 つは、列挙型フィールドが、定義された文字列ではなく内部的に保存された整数によって並べ替えられることです。

注: 列挙型の最悪の点は、文字列の追加または削除には ALTER TABLE を使用する必要があるため、将来変更される可能性がある場合を除き、列挙型を使用することはお勧めできません。要素はリストの最後にのみ追加できることが認められています。

注: Mysql は各列挙値を整数として保存し、文字列に変換するために検索を行う必要があるため、列挙型列にはある程度のオーバーヘッドが発生します。

日時型

データ型と使用法の詳細については、http://www.php.cn/

Mysql には、YEAR や DATE など、日付と時刻の値を保存できる多くの型があります。

Mysql が保存できる最小時間粒度は秒です (MariaDB はマイクロ秒レベルのイベント タイプをサポートします)。ただし、MySQL はマイクロ秒レベルの粒度でアドホック操作を実行することもできます。

ほとんどの場合、そのタイプに代わるものはないため、何が最善の選択であるかについては疑問の余地はありません。

次の唯一の問題は、日付と時刻を保存するときに何をする必要があるかです。

DATETIME

(1) この型は、1001 から 9999 までの幅広い値を秒の精度で保存できます。 (2) DATETIME は、タイム ゾーンに関係なく、時刻と日付を YYYYMMDDHHMMSS 形式の整数にカプセル化します。 (3) DATETIME は 8 バイトの記憶領域を使用します。

TIMESTAMP

(1) TIMESTAMP 型には、1970 年 1 月 1 日の午前 0 時からの秒数が格納されます。これは、UNIX タイムスタンプと同じです。 (2) TIMESTAMP は 4 バイトの記憶領域しか使用しないため、その範囲は DATETIME よりもはるかに小さくなります。 (3) TIMESTAMPで表示される値はタイムゾーンによって異なります。

DATETIME と TIMESTAMP の比較:

(1) デフォルトでは、挿入時に最初の TIMESTAMP カラムの値が指定されていない場合、Mysql はこのカラムの値を現在時刻に設定します。 (これは DATETIME にはない機能です) (2) レコードの行を挿入すると、Mysql はデフォルトで最初の TIMESTAMP カラムの値も更新します。 (3) TIMESTAMP 列のデフォルトは NOT NULL であり、他のデータ型とは異なります。

概要

(1)除了特殊行为之外,通常也应该尽可能使用TIMESTAMP,因为它比DATETIME空间效率更高。 (2)一般来讲不建议把UNIX时间戳保存为整数值,这不会带来任何收益,用整数保存时间戳格式通常不方便处理。 (3)如果需呀存储比秒更小粒度的日期和时间值,可以使用BIGINT类型存储微秒级别的时间戳,或者使用DOUBLE存储秒之后的小数部分,也可以用MariaDB替代Mysql。

位数据类型

MySQL有少数几种存储类型使用紧凑的位存储数据。所有这些位类型,不管底层存储格式和处理方式如何,从技术上来说都是字符串类型的。

BIT

可以使用BIT列在一列中存储一个或多个true/false值。BIT(1)定义了一个包含单个位的字段,BIT(2)存储2个位,依次类推。BIT列的最大长度是64位。

如果想在一个bit的存储空间中存储一个true/false值,另一个方法是创建一个可以为空的CHAR(0)列。该列可以保存空值(NULL)或者长度为零的字符串(空字符串)。

SET

多くの true/false 値を保存する必要がある場合は、これらの列を SET データ型にマージすることを検討できます。SET データ型は、MySQL によって内部的にパックされたビットのセットとして表されます。これによりストレージ領域が効率的に利用され、MySQL にはクエリで簡単に使用できる FIND_IN_SET() や FIELD() などの関数が備わっています。その主な欠点は、列定義の変更にコストがかかることです。ALTER TABLE が必要ですが、これは大きなテーブルの場合は非常にコストのかかる操作です。一般に、SET 列のインデックスを検索することもできません。

SET の代わりに、整数を使用して一連のビットをラップすることもできます。たとえば、8 ビットを TINYINT にパックし、ビット単位の演算で使用できます。アプリケーションの各ビットに名前付き定数を定義することで、これを簡素化できます。

SET と比較した場合、このメソッドの主な利点は、ALTER TABLE を使用せずにフィールドで表される「列挙」値を変更できることです。欠点は、クエリ ステートメントの記述がより難しく、理解しにくいことです。 5 番目のビットが設定されています。どういう意味ですか?)。このアプローチに非常に慣れている人もいれば、そうでない人もいるので、このテクニックを採用するかどうかは個人の好みによって決まります。

識別子 (識別子) を選択します

識別子 (識別列) に適切なデータ型を選択することが非常に重要です。

一般に、ID 列を使用して他の値と比較したり、ID 列を通じて他の列を検索したりする可能性が高くなります。

ID 列のタイプを選択するときは、ストレージ タイプだけでなく、Mysql がこのタイプに対して計算と比較を実行する方法も考慮する必要があります。

タイプを選択したら、関連するすべてのテーブルで必ず同じタイプを使用してください。

値の範囲要件が満たされ、将来の拡張の余地が確保されていることを前提として、最小のデータ型を選択する必要があります。

  • 通常、整数は高速であり、AUTO_INCREMENT で使用できるため、ID 列には最適な選択です。 AUTO_INCREMENT

  • ENUM和SET是最糟糕的选择了;

  • 如果可能也尽可能避免使用字符串作为标识列,因为它们很消耗空间并且通常比数字类慢。

特殊类型数据

某些类型的数据并不直接与内置类型一致。低于秒级精度的时间戳就是一个例子。

另一个例子是人们通常使用VARCHAR(15)来存储IP地址。然而,它们实际是32位无符号整数,不是字符串。用小数点将字段分割成四段是为了阅读方便。所以应该用无符号整数存储IP地址。MySQL提供INET_ATON()INET_NTOA()

ENUM と SET は最悪の選択です。

また、スペースを消費し、一般に数値型よりも遅いため、文字列を ID 列として使用することはできるだけ避けてください。

特殊なタイプのデータ🎜🎜一部のタイプのデータは、組み込みタイプと直接一致しません。 1 秒未満の精度のタイムスタンプは一例です。 🎜🎜もう 1 つの例は、IP アドレスを保存するために通常 VARCHAR(15) を使用することです。ただし、実際には文字列ではなく、32 ビットの符号なし整数です。読みやすくするために、フィールドを 4 つのセグメントに分割するために小数点が使用されます。したがって、IP アドレスは符号なし整数として保存する必要があります。 MySQL は、これら 2 つの表現方法の間で変換するための INET_ATON() 関数と INET_NTOA() 関数を提供します。 🎜🎜 上記は [MySQL] MySQL データ型の最適化の内容です。さらに関連する内容については、PHP 中国語 Web サイト (www.php.cn) に注目してください。 🎜🎜🎜🎜🎜
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。