Renaming DB column in referencing table (violation?) - database

Say I have this table:
Person table
--------------
PersonId
Address table
------------
AddressId
PersonAddressId
where PersonAddressId is PersonId and the foreign key. Is there any type of database violation in renaming the foreign key? It can become very confusing to work with when they have different names.

It's generally helpful to name the foreign key column the same as the primary key column it references, where possible.
Of course, sometimes it's not possible:
Two columns in Address might both be foreign keys to Person, so obviously you can't name both columns PersonId.
Some tables contain a foreign key to itself, e.g. Employee.manager_id could be a reference to Employee.employee_id. Again, you can't name the column the same as the referenced primary key in this scenario.
There are no strict naming conventions in SQL. One source for suggested metadata naming conventions is ISO 11179.

Agreed and that's why the convention is to name PersonAddressId as PersonId.

Related

Databases: Foreign key duplicates

I'm trying to understand something about the foreign key of a database.
I couldn't find a clear answer for this.
The definition of a foreign key goes something like this,
"Foreign key is a field or a group of fields in a table that refers to the primary key of another table"
OK I get that.
Then we learn about types of relationships we can have among tables using foreign keys.
In one-to-many(1:M) and many-to-many(M:N) relationships, there are duplicates in the foreign key.
But how can this be?
If a foreign key refers to a primary key and a primary key can't have duplicates, how can a foreign key can?
I'm confused.
Can someone please explain this to me?
Note - I'm expecting a common answer, not a DBMS specific one.
For example:
There is an employee table with a primary key column called EmployeeID. There is also a foreign key called SupervisorID, which references a different row in the same table.
Two employees work for the same supervisor. They will have different values in the EmployeeID field, but the same value in the SupervisorID field.
This example uses a reference back to the same table, but the concept is the same when the foreign key references a different table.

Achieving referential integrity in an Employee, Manager and Department relationship

I found a case in ER where for the life of me I can't figure out how to achieve referential integrity. The classical Employee, Manager, Department relationship can illustrate this problem.
With the following constraints:
Employee can work in only one Department.
Department can have many Employees.
Employee can have one Manager working in the same Department.
Manager can have many Employees working in the same Department.
Employee that doesn't have a Manager is a Manager.
This diagram illustrates the concept.
Before normalisation I end up with the following table.
After normalisation I end up with these tables.
However, there is still nothing stopping me from accidentally assigning a manager working in one department to an employee working in a different department in the EmployeeManager table.
One possible solution that I found was to put Department into the EmployeeManager table and define a reference integrity constraint so that {Manager, Department} refers {Employee, Department} in the EmployeeDepartment table.
However, for this to work doesn't {Manager, Department} have to be a candidate key? Is there a different design that can solve this?
Update
Ok to answer my first question, doesn't {Manager, Department} have to be a candidate key? It turns out that the {Manager, Department} in the EmployeeManager table doesn't have to be a candidate key or a unique key. It simply has to be a foreign key referencing the {Employee, Department} in the EmployeeDepartment table. The uniqueness of {Employee, Department} key isn't well defined and may differ between different engines. MySQL for example advises that the foreign keys reference only unique keys.
Additionally, MySQL requires that the referenced columns be indexed for performance reasons. However, the system does not enforce a requirement that the referenced columns be UNIQUE or be declared NOT NULL. The handling of foreign key references to nonunique keys or keys that contain NULL values is not well defined for operations such as UPDATE or DELETE CASCADE. You are advised to use foreign keys that reference only UNIQUE (including PRIMARY) and NOT NULL keys.
In my case it will work because Employee can only work in one Department however if the constraint chances to allow Employees work in many Departments it won't work because {Employee, Department} will no longer be unique.
It should work in all cases including if the constraint chances to allow Employees work in many Departments.
Is there a different design that can solve this? I also thought about replacing EmployeeDepartment with ManagerDepartment table with {Manager} as a primary key and going back to a previous EmployeeManager table with (Employee, Manager) columns. So now to find out which Department an Employee works you need to join EmployeeManager with ManagerDepartment table.
Do you see any bad practises or anomalies with this design?
Assuming all these columns are declared NOT NULL . . .
One possible solution that I found was to put Department into the
EmployeeManager table and define a reference integrity constraint so
that {Manager, Department} refers {Employee, Department} in the
EmployeeDepartment table.
Yes, add a column for "department" to the "EmployeeManager" table. But you need two foreign key constraints that overlap. (But see below . . .)
(manager, department) references EmployeeDepartment (Employee, Department)
(employee, department) references EmployeeDepartment (Employee, Department)
Since EmployeeDepartment.Employee is unique, the pair of columns EmployeeDepartment.Employee and EmployeeDepartment.Department is also unique. So you can declare "Employee" as a primary key, and also declare a unique constraint on the pair of columns (Employee, Department). Should the requirements change and allow employees to work in multiple departments, you can drop the single-column primary key. I would probably drop both the primary key and unique constraints, and create a new primary key constraint that included both columns, but all that's strictly necessary is to drop the primary key constraint.
In systems like yours, it's usually a good idea to have a table of managers, with the obvious foreign key references. Right now, if you delete the employee Will, you lose the fact that Steve is a manager.

What is the naming convention for Primary Key column? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Primary key/foreign Key naming convention
What is the naming convention for Primary Key column in Db Tables?
For instance:
PK_Country or CountryId or ID or PrimaryKey or.. ?
I like the Ruby on Rails conventions:
primary key in any table is auto-increment integer column called id
foreign keys are named as foreign table name plus _id. Example:
country_id is a foreign key that corresponds to a record from the countries table
Columns should be named based on the data elements that they represent, not based on what constraints apply to them. A primary key column should be named in the same way you name any other column. The ISO 11179 standard has some useful guidelines for naming data elements.
If the table is called Test I would call the PK column TestID.
That is pretty much up to the designer of the db. When I do it I make the field name of the primary key: id and field name of foreign keys: tablenameId
I always try to start primary keys with PK and foriegn keys with FK. Also, when naming foriegn keys, I try to include the table names and column names in the name of the foriegn key: FK_Questions-test-id_Tests-seq-num would be a foriegn key from table questions to table tests where questinos.test_id = tests.seq_num. i think it helps to name them that way for when you are glancing at your keys.
There really is not a defined standard; rather, you should develop your own convention and make sure that every primary key you define is consistent with that convention.

Database column naming for foreign key

should I signal the foreign key in a database column name?
FKOrder vs. FK_Order vs. Order
The short answer is no - don't put "FK" in column names of foreign key columns. You can still signal the intent of the column though, here's how I do it:
Naming foreign key columns
It depends on your naming convention for the target of the FK. If you have Id, then I'd prepend the table name when creating FK columns.
Example 1:
For table User with PK Id and table Workitem with user ID FK, I'd call the column Workitem.UserId.
If there were more than one FK between the same tables, I'd make this clear in the column name:
Example 2:
For table User with PK Id and table Workitem with "assigned to user ID" and "created by user ID" FKs, I'd call the columns Workitem.CreatedByUserId and Workitem.AssignedToUserId.
If your naming convention for PKs is more like UserId, then you'd factor that into the above examples so as not to end up with UserUserId.
Naming foreign key constraints
This is mine:
FK_childtablename_[differentiator]parenttablename
The differentiator is used when there is more than one FK between the same two tables (e.g. CreatedByUserId and AssignedToUserId). Often I use the child table's column name for this.
Example 1:
Given tables: Workitem and User
Where User has CreatedByUserId and AssignedToUserId
Foreign key names are FK_Workitem_User_CreatedByUser and FK_Workitem_AssignedToUser
I use double-underscores if tables/columns have underscores in the name:
Example 2:
Given tables: work_item and user
Where user has created_by_user_id and assigned_to_user_id
Foreign key names are FK_work_item__created_by_user and FK_work_item__assigned_to_user
Is usual to name the foreign key fields with an ID (IDORDER, IDPERSON, ...), if you have a table called PERSONS and another CITIES, if one person is in certain city, CITIES has an IDCITY field (K), PERSONS has a IDPERSON (K), and other field IDCITY (FK).
Hope this answers your question. I mean, a foreign key is only foreign when it's in other table, but not in theirs. But it's a good practice to name always the same to the same fields, even if they are in other tables, as a foreign key.
You shouldn't.
If a column becomes a foreign key later, you will have to change the column name, breaking all the scripts that are using it.
If there are multiple foreign keys, you don't know which column belongs to which key, so the only information you gain is that the column is a foreign key, but you already know it by looking at the keys.
Usually I name the foreign key column the same as the primary key, so I know immediately where the key maps.
I normally use the same name as the referenced column in the table holding the FK.
Only if this is potentially confusing (or a column with this name already exists, say id), would I be more explicit. In such a case, adding the entity type name before the rest - say ProductId.
My style is slightly different:
fk_table_column
eg: fk_user_id that is foreign key to User table on id column. I do not use any capital latter.

Tables with a common primary key

What's the term describing the relationship between tables that share a common primary key?
Here's an example:
Table 1
property(property_id, property_location, property_price, ...);
Table 2
flat(property_id, flat_floor, flat_bedroom_count, ...);
What you have looks like table inheritance. If your table structure is that all flat records represent a single property but not all property records refer to a flat, then that's table inheritance. It's a way of modeling something close to object-oriented relationships (in other words, flat inherits from property) in a relational database.
If I understand your example correctly, the data modeling term is Supertype/Subtype. This is a modeling technique where you define a root table (the supertype) containing common attributes, and one or more referencing tables (subtypes) that contain varying attributes based on the entities being modeled.
For example, you could have a Person table (the supertype) containing columns for attributes pertaining to all people, such as Name. You could then have an Employee table (the subtype) containing attributes specific to employees only, such as rate of pay and hire date. You could then continue this process with additional tables for other specializations of Person, such as Contractor. Each of the subtype tables would have a PersonID key column, which could be the primary key of the subtype table, as well as a foreign key referencing the Person table.
For additional info, search Google for "supertype and subtype entities", and see the links below.
http://www.learndatamodeling.com/dm_super_type.htm
http://technet.microsoft.com/en-us/library/cc505839.aspx
There isn't a good name for this relationship in common database terminology (as far as I know). It's not a one-to-one relationship because there isn't guaranteed to be a record in the "extending" table for each record in the main table. It's not a one-to-many relationship because there a maximum of one record allowed on what would otherwise be the "many" side of the relationship.
The best I can do is a one-to-one-or-none or a one-to-one-at-most relationship. (I will admit to sloppy terminology myself — I just call it a one-to-one relationship.)
Whatever you decide to call it, you can model it properly and maintain integrity in your database by making the property_id column in property a PK and the property_id column in flat a PK and also an FK back to property.
"Logic and Databases" advances the term "at most one to at most one" for this kind of relationship. (Note that it is insane to assign names to tables on account of which relationships they participate in.)
Beware of the people who have suggested things like "foreign key", "table inheritance", brief, all the other answers given here. Those people are making assumptions that you have not explicitly stated to be valid, namely that one of your two tables will be guaranteed to contain all key values that appear in the other.
(Disfunctionality of the site prevents me from adding this as a comment in the proper place.)
"How would you interpret "...that share a common primary key?" "
I interpret that in the only reasonable sense possible: that within table1, attribute values for the primary key are guaranteed to be unique, and that within table2, attribute values for the primary key are guaranteed to be unique. And that furthermore, the primary key in both tables has the same [set of] attribute names, and that the types corresponding to the primary key attribute[s] are also pairwise the same. Nothing more and nothing less.
In particular, "sharing a primary key" means "having a primary key in common", and that means in turn "having a certain 'internal uniqueness rule' in common", but that commonality guarantees in no way that a primary key value appearing in one table must also appear in the second table.
"Can you give an example involving two tables with shared primary keys where one table wouldn't contain all the key values that appear in the other?" "
Table1: column A of type integer, primary key A
Table2: column A of type integer, primary key A
Rows in table1: {A:1}. Satisfies the primary key for table1.
Rows in table2: {A:2}. Satisfies the primary key for table2.
Convinced ?
"Foreign key"?

Resources