SQL Server - Foreign Key Referencing Primary Key A OR B - sql-server

Say I have a table called Matchup that contains two sports teams. I also have a table called Pick that has a column that must match either Team_A OR Team_B. So it's a foreign key of one OR the other columns in Matchup. Is this possible?
Matchup
Team_A
Team_B
Pick
Pick_Team - FK Matchup (Must match Team_A or Team_B from Matchup).

I would split your Matchup table into two: Matchup proper and MatchupDetails.
The Matchup table would have a MatchupID column as its primary key.
The MatchupDetails one would consist of at least two columns: MatchupID to reference the Matchup table and TeamID to reference the Team table (you do have one, don't you?). The two columns would form the table's composite primary key.
Finally, there would be this Pick table. Since you've got multiple users (as per one of your comments), there would need to be a UserID reference. Two more columns, MatchupID & TeamID would serve as a composite foreign key referencing the corresponding column set in MatchupDetails. And to ensure that one user can pick no more than one team from a match-up, a composite primary key of (UserID, MatchupID) should do.
To summarise, here's a complete outline of the relevant part of the schema:
Matchup:
MatchupID
PRIMARY KEY (MatchupID)
MatchupDetails:
MatchupID
TeamID
FOREIGN KEY (MatchupID)
FOREIGN KEY (TeamID)
PRIMARY KEY (MatchupID, TeamID)
Pick:
UserID
MatchupID
TeamID
FOREIGN KEY (UserID)
FOREIGN KEY (MatchupID, TeamID)
PRIMARY KEY (UserID, MatchupID)

I dont think that this is the correct approach.
I would rather recomend that you add an additional field to table Matchup (lets say Pick) and add a CHECK CONSTRAINT to ensure that it is either Team_A or Team_B.
CHECK constraints enforce domain integrity by limiting the values that
are accepted by one or more columns. You can create a CHECK constraint
with any logical (Boolean) expression that returns TRUE or FALSE based
on the logical operators.
From FOREIGN KEY Constraints
In a foreign key reference, a link is created between two tables when
the column or columns that hold the primary key value for one table
are referenced by the column or columns in another table. This column
becomes a foreign key in the second table.
And it does not seem to be what you are looking for.

Related

Binding multiple tables to Winform

I have a Winform that will display columns from 2 tables.
The form will have a bindingnavigator.
The primary table on the form is a "child" of the second table.
I need the opposite of the usual Customer/Orders linkage
where I want to scroll thru the "orders" and automatically
pull the "customer" info.
There is one common column (ID) between the 2 tables. The ID
column in the "orders" table is not unique but the ID column
in the "customer" table is.
The primary key in the "orders" table is a composite of the ID
column and an order# column which is unique.
I was also unable to create a foreign key relationship when
choosing the ID columns in both tables.
I get this error:
"The columns in table 'orders' do not match an existing
primary key or UNIQUE constraint"
What am I missing?
If you have a composite key (I mean your question is indicating it), then you have to add both columns (ID and order) in your foreign key reference.
When table have composite key, you can see a key symbol next to columns that are part of the primary key.
When you have composite key the order of creating FK is important.
Go to keys section of table and select script of primary key as create script to clipboard (right click on primary key and choose). Paste it in new command window and then create FK with order shown in that script of primary key. (So ID and order columns need to be defined in FK in right order)

check table and foreign key table check

The system correctly set the foreign key (zemploy01-department) with the check table (zdepartmentt02-department) - inside the red box in the diagram. If i do a system check, the system says: zemploy01-department is consistant.
It is apparent that the system takes all primary keys from the check table, and tries to match it to the keys of the foreign key table. The primary key columns of check table(zdepartmentt02) are: MANDT, CAREER, DEPARTMENT, LANGUAGE. These are matched to MANDT, CAREER, DEPARTMENT columns of the foreign key table(zemploy01). However, only one column should be matched i.e. zdepartmentt02-department and zemploy01-department. Why is the system trying to match all the primary keys of the check table.
The values filled in on this wizard are the fields you have set as primary keys in the check table

SQL Server having a column as both PK and FK

I have not done much database design work and I was searching around for some example.
While I know the difference from a primary and foreign key, one thing that caught be off guard was that even if a Table has a primary key and is used as a foreign key in another table, as I was used the GUI SSMS tools, I noticed that I sometime end up having this
PhoneID (PK, int, not null)
While my User table
UserId(PK,FK, int, not null)
BOTH of these tables have these ID's as primary keys in those tables, along with foreign keys in other tables, but why does one of them have "PK,FK" obviously I accidentally created it, but should it be like that?
It is Possible for a Primary key to be a Foreign Key as well at the same time.
But looking at you database design, In your case I dont think it was intentional it was done by mistake. And if it wasnt done by mistake then you need to fix it.
In your dbo.PhoneType Table the column PhoneTypeID needs to be a Primary key only not a Foreign key. My guess is this was done by mistake, you wanted to create a Foreign key in your dbo.Phone table on column PhoneTypeID referencing PhoneTypeID column in dbo.PhoneType table. But somehow you end up create a foreign key constraint on the Primary key column of the dbo.Phontype table.
This Design contradicts constraints.
In simple english : The foreign Key Constraint on your dbo.PhoneType(PhoneTypeID) enforces that you cannot have a PhoneTypeID in dbo.PhoneType table unless it exists in PhoneTypeID column of dbo.Phone table.
On the other hand Foreign Key Constraint on dbo.Phone(PhoneTypeID) enforces that you cannot have a PhoneTypeID in dbo.Phone unless it exists in dbo.PhoneType(PhoneTypeID).
and same is true for the UserID column in dbo.Users table.
Solution
You need to drop the following Constraints to make it work properly.
1) In dbo.PhoneType table Drop Foreign key constraint referencing
PhoneTypeID column in dbo.phone table.
2) In dbo.Users Table drop the Drop Foreign key constraint referencing
UserID column in dbo.phone table.
It's entirely possible, yes. A primary key of a table could also be a foreign key referencing another table.
In your case, I'm not exactly sure what you did. You can check the constraints to see which column the UserId column is referencing.
As an additional note, simply adding a foreign reference to a table does not implicitly make that column a foreign key on another table. For example, just because you add FK_PhoneTypeID to the Phone table, SQL Server does not automatically make PhoneTypeID column in the PhoneType table a FK. In your statements, somewhere, it's possible that you made assignments to other columns, or even to themselves.

Foreign Key constraints in SQL Server

I have a database scheme with versioning data rows, e.g.
Table Person has the columns
id (int, PK)
name (String)
current (Bool)
firstid (int)
Current is 0 for previous data, 1 for the latest entry. All rows for the same entity have the same FirstID, which points to the first ID of the set.
Referencing table: Adress with the same principle:
id (int, PK)
street (String)
person_id (int)
current (Bool)
firstid (int)
Person_id points to patient.firstid. So firstid is never unique, only if current=1
My problem is: I would like to add referential integrity to my tables, but this only works, if the referenced column (patient.firstid) is unique...
You should look at refactoring your table structure. But to keep within the current structure, add a self-referencing foreign key to person
firstid references person(id)
Then, reference the "base person" from the address table
address.person_id references person(id) -- which should ONLY store a link to the first id
A FOREIGN KEY constraint does not have
to be linked only to a PRIMARY KEY
constraint in another table; it can
also be defined to reference the
columns of a UNIQUE constraint in
another table. A FOREIGN KEY
constraint can contain null values;
however, if any column of a composite
FOREIGN KEY constraint contains null
values, then verification of the
FOREIGN KEY constraint will be skipped.
Data from two related tables can be combined even if no PRIMARY KEY or FOREIGN KEY constraints are defined between the tables, but a foreign key relationship between two tables indicates that the two tables have been optimized to be combined in a query that uses the keys as its criteria.
reference http://msdn.microsoft.com/en-us/library/aa933117(v=sql.80).aspx

Are foreign keys indexed automatically in SQL Server?

Would the following SQL statement automatically create an index on Table1.Table1Column, or must one be explicitly created?
Database engine is SQL Server 2000
CREATE TABLE [Table1] (
. . .
CONSTRAINT [FK_Table1_Table2] FOREIGN KEY
(
[Table1Column]
) REFERENCES [Table2] (
[Table2ID]
)
)
SQL Server will not automatically create an index on a foreign key. Also from MSDN:
A FOREIGN KEY constraint does not have
to be linked only to a PRIMARY KEY
constraint in another table; it can
also be defined to reference the
columns of a UNIQUE constraint in
another table. A FOREIGN KEY
constraint can contain null values;
however, if any column of a composite
FOREIGN KEY constraint contains null
values, verification of all values
that make up the FOREIGN KEY
constraint is skipped. To make sure
that all values of a composite FOREIGN
KEY constraint are verified, specify
NOT NULL on all the participating
columns.
As I read Mike's question, He is asking whether the FK Constraint will create an index on the FK column in the Table the FK is in (Table1). The answer is no, and generally. (for the purposes of the constraint), there is no need to do this The column(s) defined as the "TARGET" of the constraint, on the other hand, must be a unique index in the referenced table, either a Primary Key or an alternate key. (unique index) or the Create Constraint statment will fail.
(EDIT: Added to explicitly deal with comment below -)
Specifically, when providing the data consistency that a Foreign Key Constraint is there for. an index can affect performance of a DRI Constraint only for deletes of a Row or rows on the FK side. When using the constraint, during a insert or update the processor knows the FK value, and must check for the existence of a row in the referenced table on the PK Side. There is already an index there. When deleting a row on the PK side, it must verify that there are no rows on the FK side. An index can be marginally helpful in this case. But this is not a common scenario.
Other than that, in certain types of queries, however, where the query processor needs to find the records on the many side of a join which uses that foreign key column. join performance is increased when an index exists on that foreign key. But this condition is peculiar to the use of the FK column in a join query, not to existence of the foreign Key constraint... It doesn't matter whether the other side of the join is a PK or just some other arbitrary column. Also, if you need to filter, or order the results of a query based on that FK column, an index will help... Again, this has nothing to do with the Foreign Key constraint on that column.
No, creating a foreign key on a column does not automatically create an index on that column. Failing to index a foreign key column will cause a table scan in each of the following situations:
Each time a record is deleted from the referenced (parent) table.
Each time the two tables are joined on the foreign key.
Each time the FK column is updated.
In this example schema:
CREATE TABLE MasterOrder (
MasterOrderID INT PRIMARY KEY)
CREATE TABLE OrderDetail(
OrderDetailID INT,
MasterOrderID INT FOREIGN KEY REFERENCES MasterOrder(MasterOrderID)
)
OrderDetail will be scanned each time a record is deleted in the MasterOrder table. The entire OrderDetail table will also be scanned each time you join OrderMaster and OrderDetail.
SELECT ..
FROM
MasterOrder ord
LEFT JOIN OrderDetail det
ON det.MasterOrderID = ord.MasterOrderID
WHERE ord.OrderMasterID = #OrderMasterID
In general not indexing a foreign key is much more the exception than the rule.
A case for not indexing a foreign key is where it would never be utilized. This would make the server's overhead of maintaining it unnecessary. Type tables may fall into this category from time to time, an example might be:
CREATE TABLE CarType (
CarTypeID INT PRIMARY KEY,
CarTypeName VARCHAR(25)
)
INSERT CarType .. VALUES(1,'SEDAN')
INSERT CarType .. VALUES(2,'COUP')
INSERT CarType .. VALUES(3,'CONVERTABLE')
CREATE TABLE CarInventory (
CarInventoryID INT,
CarTypeID INT FOREIGN KEY REFERENCES CarType(CarTypeID)
)
Making the general assumption that the CarType.CarTypeID field is never going to be updated and deleting records would be almost never, the server overhead of maintaing an index on CarInventory.CarTypeID would be unnecessary if CarInventory was never searched by CarTypeID.
According to: https://learn.microsoft.com/en-us/sql/relational-databases/tables/primary-and-foreign-key-constraints?view=sql-server-ver16#indexes-on-foreign-key-constraints
Unlike primary key constraints, creating a foreign key constraint does not automatically create a corresponding index

Resources