- 投稿日:2019-03-01T20:06:01+09:00
MySQLとPostgreSQLのALTER TABLEによるカラム型変更時の既存レコードの扱いの違い
どっちがどっちか忘れるので
問
ALTER TABLE後の型に変更前のレコードが相応しくない場合にどうなるか。結論
- MySQLはキャストを行う。(文字長なら切り詰めを行う)
- PostgreSQLはエラーを吐く
検証環境
mysql --version mysql Ver 14.12 Distrib 5.0.67, for unknown-linux-gnu (x86_64) using readline 5.1 psql --version psql (PostgreSQL) 9.2.18コマンド
mysql db -e "ALTER TABLE users CHANGE username username varchar(100) not null;" # 30文字以上のユーザー登録 mysql db -e "ALTER TABLE users CHANGE username username varchar(30) not null;" # エラーなし(ユーザー名は30文字まで右辺切り捨て) psql db -c "ALTER TABLE users ALTER COLUMN username TYPE varchar(100);" ALTER TABLE # 30文字以上のユーザー登録 psql db -c "ALTER TABLE users ALTER COLUMN username TYPE varchar(30);" ERROR: value too long for type character varying(30) # ユーザー削除 psql db -c "ALTER TABLE users ALTER COLUMN username TYPE varchar(30);" ALTER TABLE # または、明示的なキャストを行うと、mysqlのように切り詰められる psql db -c "ALTER TABLE users ALTER COLUMN username TYPE varchar(30) USING username::varchar(30);" ALTER TABLE参考
検索ノイズが多めだったのでここに残すことが目的
CHANGE または MODIFY を使用してデータ型を変更すると、MySQL は、既存のカラム値を新しい型にできるだけ変換しようとします。
警告この変換によって、データが変更される可能性があります。たとえば、文字列カラムを短くすると、値が切り捨てられる可能性があります。新しいデータ型への変換によってデータが失われる場合は操作が成功しないようにするには、ALTER TABLE を使用する前に厳密な SQL モードを有効にします (セクション5.1.7「サーバー SQL モード」を参照してください)。
これは、その列の既存の項目が新しい型に暗黙的キャストにより変換できる場合にのみ成功します。 より複雑な変換が必要な場合、古い値から新しい値をどのように計算するかを指定するUSING句を付けることができます。
切り捨てはしてくれても良さそうだけど。