Reputation: 1
I'm creating a table for a Customer, with a lot of columns representing possible Contracts they may have (at least one). The columns for possible contracts will have an integer which corresponds to the ID of a contract in another table.
CREATE TABLE "Customer"
(
firstName varchar(25),
lastName varchar(25),
contract0 int NOT NULL,
contract1 int,
...
contract20 int
);
CREATE TABLE "Contracts"
(
id int NOT NULL PRIMARY KEY,
svc_addr varchar(50),
...
);
My questions are:
1 - What is the easiest way to create foreign keys on all of the columns, since they could all be potentially 'pointing to' a row in the contract table? I've run across this syntax in postgres:
...
contract16 integer references Contracts(id),
...
but it seems like that will take up a lot of time in typing, which is a problem I guess, when using so many columns, which brings me to my next question...
2 - Is there an easier way to create a table with n of these 'repetitive' columns (and then possibly put the keys on them all)? Outside of making a python script, or something.
thanks
Upvotes: 0
Views: 100
Reputation: 1338
You really should consider normalizing the database structure more. In other words creating another table like this:
CREATE TABLE "Customer"
(
customerId bigserial primary key,
firstName varchar(25),
lastName varchar(25)
);
CREATE TABLE "CustomerContract"
(
customerContractId bigserial primary key,
customerId int references Customer(customerId),
contractId int references Contracts(id),
contractNumber int
);
CREATE TABLE "Contracts"
(
id int not null primary key,
svc_addr varchar(50),
...
);
First you create your customer.
Then when a contract is created, you insert into the contract row, and then tie it to a customer via the CustomerContract table.
This allows customers to have an unlimited number of contracts, without wasting space for nonexistent contracts. A side benefit is that given a contractId, you can quickly look up the customer associated with it, without having to index all of those unused contract columns in your Customer table.
Side note: I would consider changing the name of "Contracts" to be singular instead of plural (pretty much always make your table names singular). I would also change the "id" column of Contracts to contractId so that it will be clear what type of id it is when you reference it in other SQL statements.
Upvotes: 0
Reputation: 2909
Yes, there is an easier way.
If each contract is associated with only one customer, you need to put Customer_ID
into your Contracts
table and have the foreign key on that one column.
You already know one customer can have multiple contracts. If each contract can have multiple customers as well, then you have a many-to-many relationship and need a third table in the middle. For example, it could be called CustomerContracts
, and have two columns, CustomerID
and ContractID
. Then you would have two foreign keys (one for each of those columns).
Either way, the "arbitrary" part goes away.
Upvotes: 1
Reputation: 2299
Rather than using multiple contractN columns, try adding an integer ContractType column. That would correspond to the 0..20 value in your example. You can add a foreign key to a ContractType table to ensure that the number represents a valid type.
Upvotes: 0