はゼロ長(「空」)の文字列を格納することができます。 char(1)
は、1つのスペースにパディングされているため、できません。この区別があなたにとって重要である場合は、varchar
を好むかもしれません。
デザイナーは文字の大きい数は、将来的に必要とされる可能性を可能にしたい場合はそれとは別に、このための1ユースケースであってもよいです。
char(1)
からchar(2)
までの固定長データ型を変更すると、すべてのテーブル行を更新する必要があり、この列にアクセスするインデックスまたは制約が最初に削除されることを意味します。
本番環境で大規模なテーブルを変更すると、非常に時間がかかる作業になる可能性があります。それだけで(列を参照FK制約をドロップして再作成する必要はありませんが、インデックスを再構築またはデータページを更新する必要があります。)を変更するメタデータであるとしてvarchar(2)
にvarchar(1)
から列を変更
ははるかに簡単です。
さらに、1行に2バイトの節約が必ずしも実現されるとは限りません。行の定義がすでにかなり長い場合、これはデータ・ページに収まる行の数には必ずしも影響しません。もう1つのケースは、エンタープライズ版の圧縮機能を使用すると、データが格納される方法が、Mitchの答えに記載されている方法とはまったく異なる場合です。 varchar(1)
とchar(1)
の両方が短いデータ領域に同じ方法で保存されます。
@トーマスこのテーブルの定義を試してください。
CREATE TABLE T2
(
Code VARCHAR(1),
Foo datetime2,
Bar int,
Filler CHAR(4000),
PRIMARY KEY CLUSTERED (Code, Foo, Bar)
)
INSERT INTO T2
SELECT TOP 100000 'A',
GETDATE(),
ROW_NUMBER() OVER (ORDER BY (SELECT 0)),
NULL
FROM master..spt_values v1, master..spt_values v2
CREATE NONCLUSTERED INDEX IX_T2_Foo ON T2(Foo) INCLUDE (Filler);
CREATE NONCLUSTERED INDEX IX_T2_Bar ON T2(Bar) INCLUDE (Filler);
はvarchar
にとってはvarchar(2)
にvarchar(1)
から列定義を変更するのは簡単です。これはメタデータのみの変更です。変更がchar(1)
からchar(2)
にある場合
ALTER TABLE T2 ALTER COLUMN Code VARCHAR(2) NOT NULL
次の手順は起こらなければなりません。
- PKをテーブルから削除します。これにより、表がヒープに変換され、クラスタ化されていないすべての索引を、クラスタ化索引キーではなくRIDで更新する必要があることを意味します。
- 列の定義を変更します。これは、
Code
が今すぐchar(2)
として格納されるように、テーブル内のすべての行が更新されることを意味します。
- クラスタ化されたPK制約を追加し直します。 CI自体を再構築するだけでなく、非クラスタ化インデックスはすべて、RIDではなく行ポインタとしてCIキーを使用して再度更新する必要があります。
* VARCHAR(1)の実装を禁止する実装が本当に必要ないことはわかりますが、設計上のメリットがあるかどうか尋ねています。あなたの2番目の点については、明らかにするために、VARCHAR(1)は空の文字列にすることができますが、CHAR(1)はできません。わかります; CHAR(1)に対してVARCHAR(1)を選択する曖昧な理由ですが、おそらく有効なものです。 –
"•言語で定義するのが簡単です。" - あなたは抹殺できますか? –
「CASE WHEN '' = ''」が実際にTRUEになる特定のエッジケースでは微妙な反応があります。つまり、単一スペース=スペースなしですが、そのようなことを十分に認識する必要があります。オフラインでデータ型を無視するだけでは、それほどスマートではありません。 2つのポイントの後のテキストは、私が実際に見たより堅実な例を示しています。 – RichardTheKiwi