複数のテーブルに分けて管理するメリットとデメリット [SQLServer]

データベース テーブル リレーショナル

データベースでは、テーブルはできるだけ分けて管理する方がよいと言われています。

テーブルを複数に分けることにより、データを安全、確実に管理することができるためです。
また、データベースではテーブルを分けて作成し、複数のテーブルでデータを管理することで、高速にデータを取り扱うことが可能になります。

ここでは、データベースのテーブルを複数に分けることのメリットやデメリットについてまとめておきます。

使用するテーブル

本記事では、サンプルとして以下のテーブルを使用します。

テーブル定義

入出金一覧表テーブル
No 列名 データ型 PK
1 ID int 1
2 日付 nvarchar(10)
3 科目 nvarchar(30)
4 科目の区分 nvarchar(2)
5 科目の備考 nvarchar(50)
6 金額 int
7 摘要 nvarchar(50)
入出金テーブル
No 列名 データ型 PK
1 ID int 1
2 日付 nvarchar(10)
3 科目 nvarchar(30)
6 金額 int
7 摘要 nvarchar(50)
科目テーブル
No 列名 データ型 PK
1 ID int 1
2 科目名 nvarchar(30)
3 科目の区分 nvarchar(2)
4 科目の備考 nvarchar(50)
科目区分テーブル
列名 データ型 PK
1 ID int 1
2 科目区分名 nvarchar(2)

テーブルを分けるメリットとデメリット

入出金一覧表テーブルに以下のデータが格納されているとします。

No ID 日付 科目 科目の区分 科目の備考 金額 摘要
1 1001 2000/01/15 接待費 支出 取引先との食費など 15000 上杉相談役への贈答品
2 1002 2000/01/19 雑費 支出 その他の費用 250 町内会費前期分
3 1003 2000/01/20 売上 収入 売上収入(現金、売掛) 53000 デスクトップPC
4 1004 2000/01/28 接待費 支出 取引先との食費など 12360 山田商事お茶会
5 1005 2000/02/03 売上 収入 売上収入(現金、売掛) 148900 ノートPC
6 1006 2000/02/15 受取利息 収入 銀行口座等の利息 300 JP銀行預金利息
7 1007 2000/02/22 消耗品費 支出 文房具、備品などの費用 1230 単3乾電池20本
8 1008 2000/02/26 福利厚生費 支出 従業員の福利厚生に対する支出 5000 管理部従業員お茶代
9 1009 2000/02/28 接待費 支出 取引先との食費など 200000 株式上場記念パーティー

上記のデータが格納されている状態で、科目の「接待費」の名称を「接待交際費」に変更する必要が出てきた場合は、入出金一覧表テーブルの1行目、4行目、9行目の3つのレコードをすべて更新しなければなりません。

No ID 日付 科目 科目の区分 科目の備考 金額 摘要
1 1001 2000/01/15 接待交際費 支出 取引先との食費など 15000 上杉相談役への贈答品
2 1002 2000/01/19 雑費 支出 その他の費用 250 町内会費前期分
3 1003 2000/01/20 売上 収入 売上収入(現金、売掛) 53000 デスクトップPC
4 1004 2000/01/28 接待交際費 支出 取引先との食費など 12360 山田商事お茶会
5 1005 2000/02/03 売上 収入 売上収入(現金、売掛) 148900 ノートPC
6 1006 2000/02/15 受取利息 収入 銀行口座等の利息 300 JP銀行預金利息
7 1007 2000/02/22 消耗品費 支出 文房具、備品などの費用 1230 単3乾電池20本
8 1008 2000/02/26 福利厚生費 支出 従業員の福利厚生に対する支出 5000 管理部従業員お茶代
9 1009 2000/02/28 接待交際費 支出 取引先との食費など 200000 株式上場記念パーティー

また、科目自体が変更になった場合は、科目の補足情報である科目の区分と科目の備考も同時に更新する必要があります。

No ID 日付 科目 科目の区分 科目の備考 金額 摘要
1 1001 2000/01/15 接待交際費 支出 取引先との交際費用 15000 上杉相談役への贈答品
2 1002 2000/01/19 雑費 支出 その他の費用 250 町内会費前期分
3 1003 2000/01/20 売上 収入 売上収入(現金、売掛) 53000 デスクトップPC
4 1004 2000/01/28 接待交際費 支出 取引先との交際費用 12360 山田商事お茶会
5 1005 2000/02/03 売上 収入 売上収入(現金、売掛) 148900 ノートPC
6 1006 2000/02/15 受取利息 収入 銀行口座等の利息 300 JP銀行預金利息
7 1007 2000/02/22 消耗品費 支出 文房具、備品などの費用 1230 単3乾電池20本
8 1008 2000/02/26 福利厚生費 支出 従業員の福利厚生に対する支出 5000 管理部従業員お茶代
9 1009 2000/02/28 接待交際費 支出 取引先との交際費用 200000 株式上場記念パーティー

このとき、テーブルが分かれているとどうでしょうか。

入出金の一覧表が、入出金テーブルと科目テーブルに分かれているとします。

入出金テーブル
No ID 日付 科目 金額 摘要
1 1001 2000/01/15 203 15000 上杉相談役への贈答品
2 1002 2000/01/19 204 250 町内会費前期分
3 1003 2000/01/20 101 53000 デスクトップPC
4 1004 2000/01/28 203 12360 山田商事お茶会
5 1005 2000/02/03 101 148900 ノートPC
6 1006 2000/02/15 102 300 JP銀行預金利息
7 1007 2000/02/22 201 1230 単3乾電池20本
8 1008 2000/02/26 202 5000 管理部従業員お茶代
9 1009 2000/02/28 203 200000 株式上場記念パーティー
科目テーブル
No ID 科目名 科目の区分 科目の備考
1 101 売上 収入 売上収入(現金、売掛)
2 102 受取利息 収入 銀行口座等の利息
3 201 消耗品費 支出 文房具、備品などの費用
4 202 福利厚生費 支出 従業員の福利厚生に対する支出
5 203 接待費 支出 取引先との食費など
6 204 雑費 支出 その他の費用

入出金とは別に科目のテーブルがあれば、科目名を変更する必要がある場合でも、科目テーブルの対象のレコードを変更するだけで済みます。

科目テーブル
No ID 科目名 科目の区分 科目の備考
1 101 売上 収入 売上収入(現金、売掛)
2 102 受取利息 収入 銀行口座等の利息
3 201 消耗品費 支出 文房具、備品などの費用
4 202 福利厚生費 支出 従業員の福利厚生に対する支出
5 203 接待交際費 支出 取引先との交際費用
6 204 雑費 支出 その他の費用

科目テーブルは科目の区分も別のテーブルにして、以下のようにデータを格納していると、さらにデータを安全、確実に管理することができます。

科目テーブル
No ID 科目名 科目の区分 科目の備考
1 101 売上 1 売上収入(現金、売掛)
2 102 受取利息 1 銀行口座等の利息
3 201 消耗品費 2 文房具、備品などの費用
4 202 福利厚生費 2 従業員の福利厚生に対する支出
5 203 接待交際費 2 取引先との交際費用
6 204 雑費 2 その他の費用
科目区分テーブル
No ID 科目区分名
1 1 収入
2 2 支出

次に、更新対象とするレコードが非常に多い場合を考えてみます。

入出金一覧表テーブルに「接待費」という科目を持つレコードが100万行格納されている状態で、「接待費」を「接待交際費」に変更する場合、以下のようなSQLを実行することになります。

科目の情報が別のテーブルで管理されていない状態で上記のSQLを実行すると、入出金一覧表テーブルにあるすべてのレコードを更新する必要がありますので、影響を受ける行は100万件になります。

しかし、科目の情報を別のテーブルにしておけば、更新するレコードは1件のみになります。

このような処理が1つであればいいですが、頻繁に行われている環境であれば、テーブルが適切に分けられてデータが管理されていないと、サーバーに大きな負荷がかかり、パフォーマンスにも影響を与える可能性があります。

テーブルを分けて管理することにはメリットばかりのようですが、デメリットもあります。
それは、各テーブルのデータのみを人間が見た場合に理解しづらくなるという点です。

例えば、入出金テーブルにある科目列に登録されている101や201などのデータが、どの科目なのかを判別するためには、科目テーブルに登録されているすべての科目のIDと名称を知っている必要があります。

まとめ

テーブルを分けるメリット

■ データを安全、確実に管理することができる。
テーブルを分けることで、データの重複を防ぐことができます。
データベースで保持するデータの冗長を排除することができ、データの一貫性と効率性を保つことができます。

■ データを高速に扱うことができる。
更新対象のデータを最小限にすることができる。
テーブルを分けることで不要なデータを管理することがなくなるので、データの操作が高速になります。

テーブルを分けるデメリット

■ 人間には理解しずらいデータになる。
他のテーブルで管理しているデータを参照するテーブルに格納するデータは、IDやコードなどの数値や記号になります。

ただし、SQLのJOINを利用(ビューを作成)して複数のテーブルを結合し、人間が理解しやすい表形式のデータを作成することで、わかりやすいデータを作成することができます。

テーブルを分けて管理するリレーショナルデータベース

私たちが普段利用しているSQLServerなどのデータベースは、データを複数のテーブルに分けて格納し、格納されたデータを関連付けて管理、利用する様々な機能が用意されています。
このように複数のテーブルにデータを分け、それぞれのテーブルのデータを関連付けて管理するデータベースを「リレーショナルデータベース」といいます。