SQL文について勉強になったことをメモメモ（インサート→バルクインサート）

どうもこんにちは。

今回はProduction環境で動いているRailsアプリケーションのDBに祝日データを投入する際に勉強になったことをメモします。

# 祝日データとは？

[内閣府](https://www8.cao.go.jp)が毎年発表している来年の祝日の日付データです。（データといっても日付と祝日の名前しか記載されていないですが。）

以下のサイトで祝日データを閲覧、ダウンロードすることができます。

https://www8.cao.go.jp/chosei/shukujitsu/gaiyou.html

# やったこと

今回私は、データベースでSQLを実行して祝日データを投入する作業を行いました。

holiday_settingsテーブルのnameカラム、dateカラムにデータを投入するという作業です。

私は以下のSQLを作成しました。

```SQL
insert into holiday_settings(country_code,name,date,created_at,updated_at) values ('JPN','元日','2024-01-01',current_timestamp,current_timestamp);
insert into holiday_settings(country_code,name,date,created_at,updated_at) values ('JPN','成人の日','2024-01-09',current_timestamp,current_timestamp);
insert into holiday_settings(country_code,name,date,created_at,updated_at) values ('JPN','建国記念の日','2024-02-11',current_timestamp,current_timestamp);
insert into holiday_settings(country_code,name,date,created_at,updated_at) values ('JPN','休日','2024-02-12',current_timestamp,current_timestamp);
insert into holiday_settings(country_code,name,date,created_at,updated_at) values ('JPN','天皇誕生日','2024-02-23',current_timestamp,current_timestamp);
insert into holiday_settings(country_code,name,date,created_at,updated_at) values ('JPN','春分の日','2024-03-20',current_timestamp,current_timestamp);
insert into holiday_settings(country_code,name,date,created_at,updated_at) values ('JPN','昭和の日','2024-04-29',current_timestamp,current_timestamp);
insert into holiday_settings(country_code,name,date,created_at,updated_at) values ('JPN','憲法記念日','2024-05-03',current_timestamp,current_timestamp);
insert into holiday_settings(country_code,name,date,created_at,updated_at) values ('JPN','みどりの日','2024-05-04',current_timestamp,current_timestamp);
insert into holiday_settings(country_code,name,date,created_at,updated_at) values ('JPN','こどもの日','2024-05-05',current_timestamp,current_timestamp);
insert into holiday_settings(country_code,name,date,created_at,updated_at) values ('JPN','休日','2024-05-06',current_timestamp,current_timestamp);
insert into holiday_settings(country_code,name,date,created_at,updated_at) values ('JPN','海の日','2024-07-15',current_timestamp,current_timestamp);
insert into holiday_settings(country_code,name,date,created_at,updated_at) values ('JPN','山の日','2024-08-11',current_timestamp,current_timestamp);
insert into holiday_settings(country_code,name,date,created_at,updated_at) values ('JPN','休日','2024-08-12',current_timestamp,current_timestamp);
insert into holiday_settings(country_code,name,date,created_at,updated_at) values ('JPN','敬老の日','2024-09-16',current_timestamp,current_timestamp);
insert into holiday_settings(country_code,name,date,created_at,updated_at) values ('JPN','秋分の日','2024-09-22',current_timestamp,current_timestamp);
insert into holiday_settings(country_code,name,date,created_at,updated_at) values ('JPN','休日','2024-09-23',current_timestamp,current_timestamp);
insert into holiday_settings(country_code,name,date,created_at,updated_at) values ('JPN','スポーツの日','2024-10-14',current_timestamp,current_timestamp);
insert into holiday_settings(country_code,name,date,created_at,updated_at) values ('JPN','文化の日','2024-11-03',current_timestamp,current_timestamp);
insert into holiday_settings(country_code,name,date,created_at,updated_at) values ('JPN','休日','2024-11-04',current_timestamp,current_timestamp);
insert into holiday_settings(country_code,name,date,created_at,updated_at) values ('JPN','勤労感謝の日','2024-11-23',current_timestamp,current_timestamp);
```

一見何の変哲のないSQLですが、以下の点がよくないです。

- 同じSQLが複数回繰り返されている
- 見返した時にぱっと見で読みづらい（可読性が低い）

# 改善したSQL

上記のコードを見た先輩からは「バルクインサートを使用するのがおすすめ」と教えていただいたので、バルクインサートのSQLに変えてみようと思います。

```SQL
insert into holiday_settings
    (country_code,name,date,created_at,updated_at) 
values 
    ('JPN','元旦','2024-01-01',current_timestamp,current_timestamp),
    ('JPN','成人の日','2024-01-08',current_timestamp,current_timestamp),
    ('JPN','建国記念の日','2024-02-11',current_timestamp,current_timestamp),
    ('JPN','休日','2024-02-12',current_timestamp,current_timestamp),
    ('JPN','天皇誕生日','2024-02-23',current_timestamp,current_timestamp),
    ('JPN','春分の日','2024-03-20',current_timestamp,current_timestamp),
    ('JPN','昭和の日','2024-04-29',current_timestamp,current_timestamp),
    ('JPN','憲法記念日','2024-05-03',current_timestamp,current_timestamp),
    ('JPN','みどりの日','2024-05-04',current_timestamp,current_timestamp),
    ('JPN','こどもの日','2024-05-05',current_timestamp,current_timestamp),
    ('JPN','休日','2024-05-06',current_timestamp,current_timestamp),
    ('JPN','海の日','2024-07-15',current_timestamp,current_timestamp),
    ('JPN','山の日','2024-08-11',current_timestamp,current_timestamp),
    ('JPN','休日','2024-08-12',current_timestamp,current_timestamp),
    ('JPN','敬老の日','2024-09-16',current_timestamp,current_timestamp),
    ('JPN','秋分の日','2024-09-22',current_timestamp,current_timestamp),
    ('JPN','休日','2024-09-23',current_timestamp,current_timestamp),
    ('JPN','スポーツの日','2024-10-14',current_timestamp,current_timestamp),
    ('JPN','文化の日','2024-11-03',current_timestamp,current_timestamp),
    ('JPN','休日','2024-11-04',current_timestamp,current_timestamp),
    ('JPN','勤労感謝の日','2024-11-23',current_timestamp,current_timestamp);
```

インデントが入っているのもありますが、かなり見やすくなりました！
それに、SQLの実行が一回で済むのでそれもまたメリットです！

ただ、あまりにも膨大なデータをバルクインサートで投入すると、DBへの負荷が大きくなってしまうのでこまめに分けながら実行するのが良いかもしれませんね。

以上