Set on demand foreign key in DataBase - sql

I have table in my data base with these specs:
one PK
3 fields with foreign key
some statistic fields
problem is here:
In every row only one FK field will be filled.
What is the best solution A or B?
A- define 3 FK for my table
B- define one field as FK_TYPE and one field as DEMAND_FK and use checking on FK_TYPE for result

Option A - if you've got to have this design, you'll need a separate column for each foreign key. There's no (standard) way to define a "conditional" foreign key.
If your system supports check constraints, include a check constraint so that exactly one of the FK columns is not null. If it doesn't support check constraints, add triggers that enforce this same check.

If I am not wrong, B can not be possible in any relational database. Foreign key can only reference to only one primary key of a table. If you use B then you have to add the constrain in application level. Otherwise use A.

Related

How to know when to create a composite constraint?

I am currently learning SQL, and I have a physical data model I need to implement in code. However, during constraint creation, the numbers appearing next to FK and U started confusing me immensely. Consider the diagram. EDIT: Added the full physical model.
I know that when the matter is Primary Keys, we must have a single PK Constraint that's all the columns marked as PK. However, when the thing is FK or Unique constraints, I'm not so sure myself.
Let's assume I want to create the FK constraints for the table Opcao.
Should I create a single constraint for multiple columns, referencing their respective columns like this:
ALTER TABLE MySchema.Opcao ADD CONSTRAINT [FK_SUPERKEY] FOREIGN KEY ([prova], [aluno], [pergunta], [dataRealizacao])
REFERENCES MySchema.Integra([prova], [aluno], [pergunta], [dataRealizacao]);
Or create a constraint for each column, like this:
ALTER TABLE MySchema.Opcao ADD CONSTRAINT [FK_OPCAO_PROVA] FOREIGN KEY ([prova])
REFERENCES MySchema.Integra([prova]);
ALTER TABLE MySchema.Opcao ADD CONSTRAINT [FK_OPCAO_ALUNO] FOREIGN KEY ([aluno])
REFERENCES MySchema.Integra([aluno]);
ALTER TABLE MySchema.Opcao ADD CONSTRAINT [FK_OPCAO_PERGUNTA] FOREIGN KEY ([pergunta])
REFERENCES MySchema.Integra([pergunta]);
ALTER TABLE MySchema.Opcao ADD CONSTRAINT [FK_OPCAO_DATAREALIZACAO] FOREIGN KEY ([dataRealizacao])
REFERENCES MySchema.Integra([dataRealizacao]);
Would the Unique constraints follow the same logic? How do I know when to do one or the other?
You want to make a foreign key consisting of three columns which have to match all the three columns in the referenced table?
Then you should use in my oppinion on constraint for the three columns, because its the semantic you want to tell.
The one constraint for each column approach has the same effect, but you have to think a little to get the intension.
Some other tips: I don't get the semantic of the schema because i don't know the language the entities are named in. It would be easier if they were named in english. One thing i saw is the pergunta column which is duplicated and needs to be consistent in opcao, Integra und Pergunta table, this may lead to problems.
I generally helped me to always make an artifical auto increment primary key for every table (even the join tables for n to m relations), and always reference this artificial key. Then you have less problems (with case insensitivity for example) and the schema is in my oppinion easier to understand.

Are multiple foreign key constraints on the same column "ORed" or "ANDed"

In other words, if I have two foreign key constraints on the same column, will both constraints have to be met or just one in order to successfully add the record?
If you have several constraints defined on a table, then when an operation happens on the table ALL constraints needs to be met. Please note that this applies to ALL types of constraints, not only foreign constraints (that you initially questionned about) :
UNIQUE
NOT NULL
CHECK
FOREIGN KEY
See the sqlite documentation for more information about table ad column constraints.

SQL Foreign Key, is my example an appropriate use?

Can someone please confirm if this is an appropriate use of a foreign key(this is just an example):
Application to book a meeting room;
tblBooking -> pkName,Time,fkRoomName;
tblRoom -> pkRoomName, RoomNumber;
The UI will populate a dropdown menu using the pkRoomName data, when the booking is made the selected pkRoomName will then go to tblBooking fkRoomName.
Have I understood this correctly?
Yes, if you want to ensure that any booking that specifies a room refers to a known room, then this is an appropriate use of a foreign key.
Note, however, that just declaring the foreign key relationship is not the same thing as requiring that all bookings specify a room. Records in tblBooking with a NULL value for fkRoomName will be permitted. If you want to require a room is specified, you must also use the NOT NULL constraint on the fkRoomName field.
Finally, a small matter of semantics. I would not use "fk" in the column name for the RoomName. This is because a foreign key is a different entity from the columns it includes. It is not uncommon to have foreign keys that include multiple columns and it is also not uncommon to have several different foreign key relationships out of a single table. Therefore fkRoomName is an appropriate name for the foreign key itself, but not so much for the column.

What is the difference between check and foreign key?

i am quite confused about the difference between a FOREIGN KEY and CHECK constraint - they appear to me to achieve the same result.
I mean I could create a table and enforce a Foreign key on another table, but i could create a CHECK to ensure the value in in another table.
What is the difference and when to use the one or the other?
A FOREIGN KEY constrain ensures that the entry DOES EXISTS in
EDIT
another table
as per correct comment Exists in another table... or the same table. – Mark Byers
A CHECK constrain ensures that the entry follows some rule.
CHECK Constraints
CHECK constraints enforce domain integrity by limiting the values that are accepted by a column. They are similar to FOREIGN KEY constraints in that they control the values that are put in a column. The difference is in how they determine which values are valid: FOREIGN KEY constraints obtain the list of valid values from another table, and CHECK constraints determine the valid values from a logical expression that is not based on data in another column.
A foreign key constraint is more powerful than a CHECK constraint.
A foreign key constraint means that the column (in the current table) can only have values that already exist in the column of the foreign table (which can include the be the same table, often done for hierarchical data). This means that as the list of values changes - gets bigger or smaller - there's no need to update the constraint.
A check constraint can not reference any columns outside of the current table, and can not contain a subquery. Often, the values are hard coded like BETWEEN 100 and 999 or IN (1, 2, 3). This means that as things change, you'll have to update the CHECK constraint every time. Also, a foreign key relationship is visible on an Entity Relationship Diagram (ERD), while a CHECK constraint will never be. The benefit is that someone can read the ERD and construct a query from it without using numerous DESC table commands to know what columns are where and what relates to what to construct proper joins.
Best practice is to use foreign keys (and supporting tables) first. Use CHECK constraints as a backup for situations where you can't use a foreign key, not as the primary solution to validate data.
It depends on your DBMS (which you didn't specify), but in one sense, you are correct: a foreign key constraint is a particular case of a check constraint. There are DBMS which would not allow you to formulate a foreign key constraint as a check constraint.
The main intention of a check constraint is to describe conditions that apply to a single row in the table. For example, I have a table of elements (as in Hydrogen, Helium, ...) and the symbols for the elements are constrained to start with an upper-case letter and are followed by zero, one or two lower-case letters (two lower-case letters for as yet undiscovered but predicted elements: Uus - ununseptium (117), which has just been isolated but has yet to be named). This can be the subject of a CHECK constraint:
CHECK(Symbol MATCHES "[A-Z][a-z]{0,2}")
assuming MATCHES exists and supports an appropriate regular expression language.
You can also have check constraints that compare values:
CHECK(OrderDate <= ShipDate OR ShipDate IS NULL)
To express a foreign key constraint as a check constraint, you have to be permitted to execute a query in the CHECK clause. Hypothetically:
CHECK(EXISTS(SELECT * FROM SomeTable AS s
WHERE ThisTable.pk_col1 = s.pk_col1 AND
ThisTable.pk_col2 = s.pk_col2))
This example shows some of the problems. I don't have a convenient table alias for the table in which I'm writing the check constraint - I assumed it was 'ThisTable'. The construct is verbose. Assuming that the primary key on SomeTable is declared on columns pk_col1 and pk_col2, then the FOREIGN KEY clause is much more compact:
FOREIGN KEY (pk_col1, pk_col2) REFERENCES SomeTable
Or, if you are referencing an alternative key, not the primary key:
FOREIGN KEY (pk_col1, pk_col2) REFERENCES SomeTable(ak_col1, ak_col2)
This is notationally more compact - so there is less chance of getting it wrong - and can be special-cased by the server because the special notation means it knows that it is dealing with a foreign key constraint whereas the general check clause has to be scrutinized to see if it matches one of many possible forms that are equivalent to the foreign key.
The question asks: when to use a check constraint and when to use a foreign key constraint?
Use a CHECK constraint to specify criteria that can be checked in a single row.
Use a FOREIGN KEY constraint to specify that the values in the current row must match the values of a row in some other unique key (a candidate key, usually the primary key rather than an alternative key) of some table - which may be the same table or (more usually) a different table.
Consider a scenario like this:
Table A has a keyword column, and the value must be among thousand of keywords provided.
How would you like to implement the constraint?
Hard coded check condition like check (keyword in ('a', 'b', 'c' .......)) or simply import the provided keywords as another table and set a foreign key constraint to keyword column of Table A.

How do I clear a table with a lot of references in oracle?

For instance, suppose I have table A. Then I have tables B-Z that have a foreign key to table A's primary key. Then perhaps there are also some tables that have a foreign key constraint to a table in B-Z's primary key constraint. Is there any easy way to clear out table A and all of the tables that refer to A (or that refer to a table that refers to A) without having to explicitly delete from each table or add an ON CASCADE constraint to each foreign key?
Note that this is mainly for testing purposes, not to be used in production. I would just drop the entire schema and start over again, but that simply isn't feasible for every test (considering how long it takes to build the schema).
I think the most efficient way to do this would be to drop all the FK's, truncate the tables, and then rebuild the FK's.