is_active
is_deleted
is_admin
CREATE TABLE users ( id INT PRIMARY KEY, name VARCHAR(255), is_active TINYINT(1) -- 0 = false, 1 = true );
このフラグを「文字列」で管理すると次の問題が発生
CHAR(1)
"0"
"1"
VARCHAR(3)
"yes"
"no"
TINYINT(1)
BOOLEAN
SELECT * FROM users WHERE is_active = 'yes';
-> TINYINT(1) or BOOLEANならインデックスを使える
BigQueryはスキャンしたデータ量で課金されるため、無駄なストレージ消費はコスト増につながるので注意!!!!!
BOOL
0, 1
'yes'
'no'
"YES"
"Yes"
SELECT * FROM users WHERE is_active = 'YES';
→ 'YES' と 'yes' を区別するかどうかは DB の設定次第でバグのもと!
'YES'
"y"
"n"
"true"
INSERT INTO users (name, is_active) VALUES ('Alice', 'active');
→ ENUM('yes', 'no') で制限をかけるか、数値型を使うべき!
ENUM('yes', 'no')
CREATE TABLE users ( id INT PRIMARY KEY, name VARCHAR(255), is_active TINYINT(1) NOT NULL DEFAULT 1 );
0 = false
1 = true
ENUM
CREATE TABLE users ( id INT PRIMARY KEY, name VARCHAR(255), status ENUM('active', 'inactive') NOT NULL DEFAULT 'active' );
status
外部テーブル
CREATE TABLE user_status ( user_id INT PRIMARY KEY, status_id INT, FOREIGN KEY (status_id) REFERENCES statuses(id) );
CREATE INDEX idx_status ON users(status_id)
CREATE TABLE users ( id SERIAL PRIMARY KEY, name VARCHAR(255), is_active BOOLEAN, created_at TIMESTAMP NOT NULL ) PARTITION BY RANGE (created_at); CREATE TABLE users_2023 PARTITION OF users FOR VALUES FROM ('2023-01-01') TO ('2023-12-31'); CREATE TABLE users_2024 PARTITION OF users FOR VALUES FROM ('2024-01-01') TO ('2024-12-31');
SELECT
WHERE is_deleted = 0
deleted_at
CREATE TABLE users ( id INT PRIMARY KEY, name VARCHAR(255), deleted_at TIMESTAMP NULL );
deleted_users
CREATE TABLE user_status_history ( id SERIAL PRIMARY KEY, user_id INT, status_id INT, changed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );
文字列型フラグはストレージ効率・パフォーマンスが悪い BOOLEAN / TINYINT(1) の方が整合性を保ちやすい どうしても文字列を使うなら ENUM を活用 DB 設計では、データの型を慎重に選ぼう! 失敗から学ぶRDBの正しい歩き方を読め