简体   繁体   中英

Identity column separate from composite primary key

I have a table representing soccer matches:

  • Date
  • Opponent

I feel {Date,Opponent} is the primary key because in this table there can never be more than one opponent per date. The problem is that when I create foreign key constraints in other tables, I have to include both Date and Opponent columns in the other tables:

Soccer game statistics table:

  • Date
  • Opponent
  • Event (Goal scored, yellow card etc)

Ideally I would like to have:

Soccer matches table:

  • ID
  • Date
  • Opponent

Soccer match statistics table:

  • SoccerMatchID
  • Event (Goal scored, yellow card etc)

where SoccerMatch.ID is a unique ID (but not the primary key) and {Date,Opponent} is still the primary key.

The problem is SQL Server doesn't seem to let me define ID as being a unique identity whilst {Date,Component} is the primary key. When I go to the properties for ID, the part signalling unique identifying is grayed-out with "No".

(I assume everyone agrees I should try to achieve the above as it's a better design?)

I think most people don't use the graphical designer to do this, as it's the graphical designer that's preventing it, not SQL Server. Try running DDL in a query window:

ALTER TABLE dbo.YourTable ADD ID INT IDENTITY(1,1);
GO
CREATE UNIQUE INDEX yt_id ON dbo.YourTable(ID);
GO

Now you can reference this column in other tables no problem:

CREATE TABLE dbo.SomeOtherTable
(
  MatchID INT FOREIGN KEY REFERENCES dbo.YourTable(ID)
);

That said, I find the column name ID completely useless. If it's a MatchID , why not call it MatchID everywhere it appears in the schema? Yes it's redundant in the PK table but IMHO consistency throughout the model is more important.

For that matter, why is your table called SoccerMatch ? Do you have other kinds of matches? I would think it would be Matches with a unique ID = MatchID . That way if you later have different types of matches you don't have to create a new table for each sport - just add a type column of some sort. If you only ever have soccer, then SoccerMatch is kind of redundant, no?

Also I would suggest that the key and unique index be the other way around. If you're not planning to use the multi-column key for external reference then it is more intuitive, at least to me, to make the PK the thing you do reference in other tables. So I would say:

CREATE TABLE dbo.Matches
(
  MatchID INT IDENTITY(1,1),
  EventDate DATE, -- Date is also a terrible name and it's reserved
  Opponent <? data type ?> / FK reference?
);

ALTER TABLE dbo.Matches ADD CONSTRAINT PK_Matches
  PRIMARY KEY (MatchID);

ALTER TABLE dbo.Matches ADD CONSTRAINT UQ_Date_Opponent
  UNIQUE (EventDate, Opponent);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM