web-dev-qa-db-ja.com

照合順序が列レベルで指定されているのはなぜですか?

文字セットは、行データをファイルストアに保存する方法を定義します。

Row 17: <CHARSET('utf8', 'hello'), 17, CHARSET('latin-1', 'sup')>

しかし、照合はこれらの行のソートにのみ影響するようです。

それでは、列を定義するときに照合が指定されているのはなぜですか?

代わりに、並べ替え行で重要なもの、つまりインデックス(並べ替えられて格納されているため)、クエリ(等しいかどうかをテストするため)、および制約(事実上クエリであるため)を定義する場合にのみ、照合順序を指定すると思います。

2

MySQL/MariaDBが私が知らないことをしない限り(通常はSQL Serverに焦点を当てているため):エンコード(つまり、「文字セット」)は個別に処理されるため、列レベルの照合はデフォルトである必要があります言及した操作(インデックス、クエリなどの作成)、およびの比較に使用されるため、照合順序を指定する必要はありません。 毎回(特定のルールが提供されていない場合、文字列は比較またはソートできません)。これにより、クエリが非常に複雑になるだけでなく、列レベル(または少なくともDBレベル)で宣言されていないため、クエリの一貫性を提供することがほぼ不可能になり、クエリ開発者にデータの意図を思い出させることになります。モデラー、そしてそれは確かに成功のためのレシピではありません;-)。

列レベルで指定されていない場合、照合は少なくともデータベースレベルまたはインスタンスレベルでさえ指定する必要があります(そして、どちらかのレベルで指定するRDBMSがあり、列で指定することさえできないと思いますレベル)。

照合順序を指定する必要があるだけですどこか。それ以外の場合は、照合順序を指定せずにインデックスを再構築(単独で作成すること)することもできません。また、列レベルで照合を指定する細分性を許可すると、テーブル内または同じデータベース内のテーブル間で異なる文字列列が異なるニーズ/要件を簡単に持つことができるため、最大の柔軟性が得られます。

また、補足として、SQL ServerなどのRDBMSの場合、単一の「照合」で照合と照合を組み合わせます(2つを分離する方法はありません)。列レベルで指定する必要があるため、エンコーディング(少なくともVARCHAR/CHAR/TEXT列の場合; NVARCHAR/NCHAR/NTEXTは常にUTFです-16 LE)。

1
Solomon Rutzky

(OP)しかし、照合はこれらの行のソートにのみ影響するようです。

それは真実ではない。

CREATE TABLE test1 (txt VARCHAR(4) COLLATE 'latin1_general_ci')
SELECT 'Test' txt UNION ALL
SELECT 'TEST'     UNION ALL
SELECT 'tEsT';
CREATE TABLE test2 (txt VARCHAR(4) COLLATE 'latin1_general_cs')
SELECT 'Test' txt UNION ALL
SELECT 'TEST'     UNION ALL
SELECT 'tEsT';
SELECT COUNT(DISTINCT txt)
FROM test1;
 | COUNT(DISTINCT txt)| 
 | ------------------:| 
 | 1 | 
SELECT COUNT(DISTINCT txt)
FROM test2;
 | COUNT(DISTINCT txt)| 
 | ------------------:| 
 | 3 | 

db <> fiddle ここ

クエリで照合を指定する場合も同様です。

SELECT COUNT(DISTINCT CONVERT(txt USING 'latin1_general_c?'))
FROM test;

(OP)列を定義するときに照合が指定されるのはなぜですか?

照合の粒度は単一の値です。

1
Akina