社内の資産管理台帳を作りたいと考えています。
管理対象は、社員が利用しているPCと、各PCにインストールしているソフトです。
以下の3点が前提条件としてあります。
1.一人の社員が複数のPCを使用する場合がある
2.ソフトはライセンスの種別により利用可能対象が異なる
・タイプA:PC1台につき1ライセンス
・タイプB:ユーザー1人につき2台まで
3.各ソフトウェアごと利用状況(使用中/在庫)を集計したい
多対多の関係になるため、連結用のテーブルを使うことを考えましたが、
どのようなSQLを書けば3の集計ができるのかわかりませんでした。
そもそも設計として正しいのか、SQLはどのようになるのかをご教示いただければと思います。
[ユーザー]
│
│
[連結用]────[パソコン]
│
│
[ソフトウェア]
[ユーザー]
ID 社員
1 田中 一郎
2 山田 太郎
3 太田 光博
4 佐川 和夫
5 太田 明日香
6 篠原 沙希
7 朝霞 寛子
[パソコン]
ID PC識別番号
1 H001
2 H002
3 H003
4 H004
5 H005
6 H006
[ソフトウェア]
ID ソフト名称 タイプ 購入数
1 Office2010 Professional A 5
2 Office2010 Personal B 5
3 Office2013 Professional B 5
4 Office365 B 20
5 Illustrator CS4 A 4
6 Photoshop CS4 A 4
7 Dreamweaver CS4 A 4
8 InDesign CS4 B 3
9 Illustrator CS5 B 6
10 Photoshop CS5 B 6
11 Dreamweaver CS5 B 6
12 InDesign CS5 B 2
13 CreativeCloud B 2
14 Acrobat A 30
[連結用]
社員 PC ソフト
田中 一郎 H001 Office2010 Professional
田中 一郎 H001 Acrobat
山田 太郎 H003 Acrobat
山田 太郎 H003 CreativeCloud
佐川 和夫 H004 Acrobat
佐川 和夫 H004 Illustrator CS5
佐川 和夫 H004 Photoshop CS5
佐川 和夫 H004 Dreamweaver CS5
篠原 沙希 H002 Office2013 Professional
篠原 沙希 H002 Acrobat
田中 一郎 H006 Office2013 Professional
田中 一郎 H006 Acrobat
朝霞 寛子 H003 Illustrator CS4
朝霞 寛子 H003 Photoshop CS4
朝霞 寛子 H003 Dreamweaver CS4
※実際には各IDが入ります
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

回答3件
0
多対多の関連を表すのに関連テーブルを使うのは定石ではありますが、関連テーブルの設計に少し問題があるように思います。
以下の仕様が実際の業務にマッチするかはわかりませんが、提案させていただきます。
ライセンスタイプBの「ユーザー1人につき2台まで」という条件が少しややこしいので、
これを整理して、
0.「AタイプのライセンスはPCごとにライセンスされる」
0.「Bタイプのライセンスはユーザーごとにライセンスされる」
0.「Bタイプのライセンスは、1ユーザーにつき、PC2台までインストールできる」
という3つの条件として区別して考えるというのはいかがでしょうか。
そして、ライセンス数の在庫に影響するのは1と2であり、3の条件が守られているかどうかを別の問題として考えるとすると、在庫数に関しては以下のように管理できるかと思います。
【テーブル構成】
sql
1/* ユーザー */ 2CREATE TABLE USER( 3 ID INT NOT NULL PRIMARY KEY, 4 NAME VARCHAR(24) 5); 6 7/* パソコン */ 8CREATE TABLE PC( 9 ID INT NOT NULL PRIMARY KEY, 10 SERIAL VARCHAR(4) NOT NULL 11); 12 13/* ソフトウェア */ 14CREATE TABLE SOFTWARE( 15 ID INT NOT NULL PRIMARY KEY, 16 NAME VARCHAR(64), 17 TYPE VARCHAR(1), 18 CNT INT 19); 20 21/* ライセンスタイプ:A */ 22/* どのPCにどのソフトウェアがインストールされているのか */ 23CREATE TABLE R_PC_SOFT( 24 PID INT NOT NULL, /* PC.ID */ 25 SID INT NOT NULL, /* SID.ID */ 26 PRIMARY KEY(PID, SID) 27); 28 29/* ライセンスタイプ:B */ 30/* どのユーザーがどのPCにどのソフトをインストールして使用しているのか */ 31CREATE TABLE R_USER_SOFT( 32 UID INT NOT NULL, /* USER.ID */ 33 PID INT NOT NULL, /* PC.ID */ 34 SID INT NOT NULL, /* SOFTWARE.ID */ 35 PRIMARY KEY(UID, PID, SID) 36);
(FKは省略しましたが、実際には付けた方が良いと思います)
【テストデータ】
sql
1INSERT INTO USER VALUES(1, '田中 一郎'); 2INSERT INTO USER VALUES(2, '山田 太郎'); 3INSERT INTO USER VALUES(3, '太田 光博'); 4INSERT INTO USER VALUES(4, '佐川 和夫'); 5INSERT INTO USER VALUES(5, '太田 明日香'); 6INSERT INTO USER VALUES(6, '篠原 沙希'); 7INSERT INTO USER VALUES(7, '朝霞 寛子'); 8 9INSERT INTO PC VALUES(1, 'H001'); 10INSERT INTO PC VALUES(2, 'H002'); 11INSERT INTO PC VALUES(3, 'H003'); 12INSERT INTO PC VALUES(4, 'H004'); 13INSERT INTO PC VALUES(5, 'H005'); 14INSERT INTO PC VALUES(6, 'H006'); 15 16INSERT INTO SOFTWARE VALUES(1, 'Office2010 Professional', 'A', 5); 17INSERT INTO SOFTWARE VALUES(2, 'Office2010 Personal', 'B', 5); 18INSERT INTO SOFTWARE VALUES(3, 'Office2013 Professional', 'B', 5); 19INSERT INTO SOFTWARE VALUES(4, 'Office365', 'B', 20); 20INSERT INTO SOFTWARE VALUES(5, 'Illustrator CS4', 'A', 4); 21INSERT INTO SOFTWARE VALUES(6, 'Photoshop CS4', 'A', 4); 22INSERT INTO SOFTWARE VALUES(7, 'Dreamweaver CS4', 'A', 4); 23INSERT INTO SOFTWARE VALUES(8, 'InDesign CS4', 'B', 3); 24INSERT INTO SOFTWARE VALUES(9, 'Illustrator CS5', 'B', 6); 25INSERT INTO SOFTWARE VALUES(10, 'Photoshop CS5', 'B', 6); 26INSERT INTO SOFTWARE VALUES(11, 'Dreamweaver CS5', 'B', 6); 27INSERT INTO SOFTWARE VALUES(12, 'InDesign CS5', 'B', 2); 28INSERT INTO SOFTWARE VALUES(13, 'CreativeCloud', 'B', 2); 29INSERT INTO SOFTWARE VALUES(14, 'Acrobat', 'A', 30); 30 31INSERT INTO R_PC_SOFT VALUES(1, 1); 32INSERT INTO R_PC_SOFT VALUES(1, 14); 33INSERT INTO R_PC_SOFT VALUES(3, 14); 34INSERT INTO R_PC_SOFT VALUES(4, 14); 35INSERT INTO R_PC_SOFT VALUES(2, 14); 36INSERT INTO R_PC_SOFT VALUES(6, 14); 37INSERT INTO R_PC_SOFT VALUES(3, 5); 38INSERT INTO R_PC_SOFT VALUES(3, 6); 39INSERT INTO R_PC_SOFT VALUES(3, 7); 40 41INSERT INTO R_USER_SOFT VALUES(2, 3, 13); 42INSERT INTO R_USER_SOFT VALUES(4, 4, 9); 43INSERT INTO R_USER_SOFT VALUES(4, 4, 10); 44INSERT INTO R_USER_SOFT VALUES(4, 4, 11); 45INSERT INTO R_USER_SOFT VALUES(6, 2, 3); 46INSERT INTO R_USER_SOFT VALUES(6, 2, 14); 47INSERT INTO R_USER_SOFT VALUES(1, 6, 3); 48INSERT INTO R_USER_SOFT VALUES(1, 6, 14);
【ライセンス在庫数を確認するSQLサンプル】
sql
1select 2 s.id as "ソフトウェアID", 3 s.name as "名称", 4 s.type as "タイプ", 5 s.cnt as "購入数", 6 ifnull(u.used, 0) as "使用数", 7 ifnull(s.cnt - u.used, 0) as "在庫" 8from software as s 9 left outer join (select sid, count(sid) as used from r_pc_soft group by sid) as u 10 on s.id = u.sid 11where s.type = 'A' 12union 13select 14 s.id as "ソフトウェアID", 15 s.name as "名称", 16 s.type as "タイプ", 17 s.cnt as "購入数", 18 ifnull(u.used, 0) as "使用数", 19 ifnull(s.cnt - u.used, 0) as "在庫" 20from software as s 21 left outer join (select sid, count(sid) as used from r_user_soft group by sid) as u 22 on s.id = u.sid 23where type = 'B' 24order by 1;
【問い合わせ結果】
+----------------------+-------------------------+-----------+-----------+-----------+--------+ | ソフトウェアID | 名称 | タイプ | 購入数 | 使用数 | 在庫 | +----------------------+-------------------------+-----------+-----------+-----------+--------+ | 1 | Office2010 Professional | A | 5 | 1 | 4 | | 2 | Office2010 Personal | B | 5 | 0 | 0 | | 3 | Office2013 Professional | B | 5 | 2 | 3 | | 4 | Office365 | B | 20 | 0 | 0 | | 5 | Illustrator CS4 | A | 4 | 1 | 3 | | 6 | Photoshop CS4 | A | 4 | 1 | 3 | | 7 | Dreamweaver CS4 | A | 4 | 1 | 3 | | 8 | InDesign CS4 | B | 3 | 0 | 0 | | 9 | Illustrator CS5 | B | 6 | 1 | 5 | | 10 | Photoshop CS5 | B | 6 | 1 | 5 | | 11 | Dreamweaver CS5 | B | 6 | 1 | 5 | | 12 | InDesign CS5 | B | 2 | 0 | 0 | | 13 | CreativeCloud | B | 2 | 1 | 1 | | 14 | Acrobat | A | 30 | 5 | 25 | +----------------------+-------------------------+-----------+-----------+-----------+--------+
おそらく、やりたいことはこんな感じなのではと推測したのですが、いかがでしょうか。
ライセンスタイプBの「ユーザー1人につき2台まで」の条件が満たされているかどうかはアプリ側で制御する前提で考えましたが、それをDB側でチェックするのであれば、トリガーでチェックするような形になるかと思います。
投稿2015/11/13 11:49
編集2015/11/13 13:11総合スコア27
0
ソフトウェア識別番号 | ライセンス番号 | ライセンス連番 | ライセンスタイプ | Microsoft-001-2010-P | 123-456-789-012 | 1 | A | Microsoft-001-2010-P | 123-456-789-013 | 1 | A | Microsoft-001-2010-P | 123-456-789-014 | 1 | A | Microsoft-001-2010-P | 123-456-789-015 | 1 | A | Microsoft-001-2010-P | 123-456-789-016 | 1 | A | Microsoft-002-365 | 123-456-789-017 | 1 | A | Microsoft-002-365 | 123-456-789-017 | 2 | A | Microsoft-002-365 | 123-456-789-017 | 3 | A | Microsoft-002-365 | 123-456-789-017 | 4 | A | Microsoft-002-365 | 123-456-789-017 | 5 | A |
PC識別番号 PC0123456 PC0123457 PC0123458 PC0123459 PC0123460
ソフトウェア利用状況 PC識別番号 | ソフトウェア識別番号 | ライセンス番号 | ライセンス連番 PC0123456 | Microsoft-001-2010-P | 123-456-789-012 | 1 PC0123456 | Microsoft-002-365 | 123-456-789-017 | 1 PC0123457 | Microsoft-001-2010-P | 123-456-789-012 | 1 PC0123458 | Microsoft-002-365 | 123-456-789-017 | 2 PC0123459 | Microsoft-002-365 | 123-456-789-017 | 3
ユーザーテーブル 社員ID | 社員名 00000001 | 山田太郎 00000002 | 佐藤二郎 00000003 | 鈴木三郎
パソコン利用状況テーブル 社員ID |PC識別番号 00000001 |PC0123456 00000002 |PC0123457 00000001 |PC0123458
select ソフトウェア.ソフトウェア識別番号, ソフトウェア利用状況.PC識別番号, 社員ID from ソフトウェア left outer join ソフトウェア利用状況 on ソフトウェア.ソフトウェア識別番号 = ソフトウェア利用状況.ソフトウェア識別番号 left outer join パソコン利用状況テーブル on ソフトウェア利用状況.PC識別番号 = パソコン利用状況テーブル.PC識別番号 left outer join ユーザーテーブル on パソコン利用状況テーブル.社員ID = ユーザーテーブル.社員ID
すみません、結構適当なので他の方のブラッシュアップを期待します。
投稿2015/11/13 09:49
総合スコア856
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

0
正規化の入門レベルの内容ですが、
1.一人の社員が複数のPCを使用する場合がある
ある社員がどのパソコンを使っているか、複数の社員が同じパソコンを使っている場合のライセンスのカウントを表現する情報(テーブルひとつ追加で済むか?)が必要です。
現状用意できる CREATE TABLE, INSERT文も提示できるとコメントも付きやすいでしょう。
PRIMARY KEYに相当する列がIDですと誤解し易いので、列名ひとつとっても分かり易いネーミングを考えてください。
投稿2015/11/13 09:41
総合スコア16417
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/11/16 01:48 編集
2015/11/16 04:27