Related
Consider the following model where a Customer should have one and only one Address and an Address should belong to one and only one Customer:
To implement it, as almost everybody in DB field says, Shared PK is the solution:
But I think it is a fake one-to-one relationship. Because nothing in terms of database relationship actually prevents deleting any row in table Address. So truely, it is 1..[0..1] not 1..1
Am I right? Is there any other way to implement a true 1..1 relation?
Update:
Why cascade delete is not a solution:
If we consider cascade delete as a solution we should put this on either of the tables. Let's say if a row is deleted from table Address, it causes corresponding row in table Customer to be deleted. it's okay but half of the solution. If a row in Customer is deleted, the corresponding row in Address should be deleted as well. This is the second half of the solution, and it obviously makes a cycle.
Beside my comment
You could implement DELETE CASCADE See HOW
I realize there is also the problem of insert.
You have to insert Customer first and then Address
So I think the best way if you really want a 1:1 is create a single table instead.
Customer
CustomerID
Name
Address
City
Sorry, is this meant to be a real-world database relationship? In all of the many databases I have ever built with customer data, there has always been real cases of either customers with multiple addresses, or more than one organisation at the same address.
I wouldn't want to lead you into a database modelling fallacy by suggesting anything different.
Yes, the "shared PK" idiom you show is for 1-to-0-or-1.
The straightforward way to have a true 1-to-1 correspondence is to have one table with Customer and Address as CKs (candidate keys). (Via UNIQUE NOT NULL and/or PRIMARY KEY.) You could offer the separate tables as views. Unfortunately typical DBMSs have restrictions on what you can do via the views, in particular re updating.
The relational way to have separate CUSTOMER and ADDRESS tables and a third table/association/relationship with Customer and Address columns as CKs plus FKs on Customer to and from CUSTOMER and on Address to and from ADDRESS (or equivalent constraint(s)). Unfortunately most DBMSs needlessly won't let you declare cycles in FKs and you cannot impose the constraints without triggers/complexity. (Ultimately, if you want to have proper integrity in a typical SQL database you need to use triggers and complex idioms.)
Entity-oriented design methods unfortunately artificially distinguish between entities, associations and properties. Here is an example where if you consider the simplest design to simply be the one table with PKs then you don't want to always have to have distinct tables for each entity. Or if you consider the simplest design to be the three tables (or even two) with the PKs and FKs (or some other constraint(s) for 1-to-1) then unfortunately typical DBMSs just don't declaratively/ergonomically support that particular design situation.
(Straightforward relational design is to have values (that are sometimes used as ids) 1-to-1 with application things but then just have whatever relevant application relationships/associations/relations and corresponding/representing tables/relations as needed to describe your application situations.)
It's possible in principle to implement a true 1-1 data structure in some DBMSs. It's very difficult to add data or modify data in such a structure using standard SQL however. Standard SQL only permits one table to be updated at a time and therefore as soon as you insert a row into one or other table the intended constraint is broken.
Here are two examples. First using Tutorial D. Note that the comma between the two INSERT statements ensures that the 1-1 constraint is never broken:
VAR CUSTOMER REAL RELATION {
id INTEGER} KEY{id};
VAR ADDRESS REAL RELATION {
id INTEGER} KEY{id};
CONSTRAINT one_to_one (CUSTOMER{id} = ADDRESS{id});
INSERT CUSTOMER RELATION {
TUPLE {id 1234}
},
INSERT ADDRESS RELATION {
TUPLE {id 1234}
};
Now the same thing in SQL.
CREATE TABLE CUSTOMER (
id INTEGER NOT NULL PRIMARY KEY);
CREATE TABLE ADDRESS (
id INTEGER NOT NULL PRIMARY KEY);
INSERT INTO CUSTOMER (id)
VALUES (1234);
INSERT INTO ADDRESS (id)
VALUES (1234);
ALTER TABLE CUSTOMER ADD CONSTRAINT one_to_one_1
FOREIGN KEY (id) REFERENCES ADDRESS (id);
ALTER TABLE ADDRESS ADD CONSTRAINT one_to_one_2
FOREIGN KEY (id) REFERENCES CUSTOMER (id);
The SQL version uses two foreign key constraints, which is the only kind of multi-table constraint supported by most SQL DBMSs. It requires two INSERT statements which means I could only insert a row before adding the constraints, not after.
A strict one-to-one constraint probably isn't very useful in practice but it's actually just a special case of something more important and interesting: join dependency. A join dependency is effectively an "at least one" constraint between tables rather than "exactly one". In the world outside databases it is common to encounter examples of business rules that ought to be implemented as join dependencies ("each customer must have AT LEAST ONE addresss", "each order must have AT LEAST ONE item in it"). In SQL DBMSs it's hard or impossible to implement join dependencies. The usual solution is simply to ignore such business rules thus weakening the data integrity value of the database.
Yes, what you say is true, the dependent side of a 1:1 relationship may not exist -- if only for the time it takes to create the dependent entity after creating the independent entity. In fact, all relationships may have a zero on one side or the other. You can even turn the relationship into a 1:m by placing the FK of the address in the Customer row and making the field not null. You can still have addresses that aren't referenced by any customer.
At first glance, a m:n may look like an exception. The intersection entry is generally defined so that neither FK can be null. But there can be customers and addresses both that have no entry referring to them. So this is really a 0..m:0..n relationship.
What of it? Everyone I've ever worked with has understood that "one" (as in 1:1) or "many" (as in 1:m or m:n) means "no more than this." There is no "exactly this, no more or less." For example, we can design a 1:3 relationship on paper. We cannot strictly enforce it in any database. We have to use triggers, stored procedures and/or scheduled tasks to seek out and call our attention to deviations. Execute a stored procedure weekly, for instance, that will seek and and flag or delete any such orphaned addresses.
Think of it like a "frictionless surface." It exists only on paper.
I see this question as a conceptual misunderstanding. Relations are between different things. Things with a "true 1-to-1 relation" are by definition aspects or attributes of the same thing, and belong in the same table. No, of course a person and and address are not the same, but if they are inseparable, and must always be inserted, deleted, or otherwise acted upon as a unit, then as data they are "the same thing". This is exactly what is described here.
Yes, and it's actually quite easy: just put both entities in the same table!
OTOH, if you need to keep them in separate tables for some reason, then you need a key in one table referencing1 a key in another, and vice-versa. This, of course, represents a "chicken and egg" problem2 which can be resolved by deferring the enforcement of FKs to the end of the transaction3. This works only on DBMSes that support deferred constraints (such as Oracle and PostgreSQL).
1 Via a foreign key.
2 Inserting a row in the first table is impossible because that would violate the referential integrity towards the second table, but inserting a row in the second table is impossible because that would violate the referential integrity towards the first table, etc... Ditto for deletion.
3 So you simply insert both rows, and then check both FKs.
I have a trip (primary: idTrip), where I can link more packages (primary: idPackage), so, I got a relationship table to link trips with packages (primary: idRelTripPackage). (relationship n-to-n)
And next I got a registrations table (primary: idRegistration). How do I best link those (1-to-1 relationship)?
I add two columns in the registrations table (idTrip, idPackage)?
I add a relationship table where i link idRegistration, idTrip, idPackage?
I add a relationship table where i link idRegistration, idRelTripPackage?
Am I right in thinking the relation from Registrations is to RelTripPackage, and its definitely one-to-one. There are a couple of options:
1: As it really is a one-to-one there's not really anything to stop you putting the Registrations data directly onto RelTripPackage, or doing the vice-versa and putting idPackage and idTrip straight onto Registrations as FKs, with a unique key across the two FK columns to ensure there aren't duplicates.
2: If do want the two separate tables then just add idRetTripPackage to Registrations as an FK, and then add a unique constraint on it - again to ensure uniqueness.
There's no need for a separate relationship table as its a 1-1 relationship - They only really become relevant when you are using an n-n. The rest of the time FKs should be placed directly on the child table.
If you follow that logic, you will
add tables and Relations every time you need to add Relations
end up with confusing or duplicate Relations (multiple paths between any two tables)
However the problem (limiting factor) is that the tables you are starting with are not actually normalised. Since the starting position does not have a good basis, you will end up with far more Relations (in tables) than there actually are between the Entities. So the best advice is, the Best practice is, before you attempt this current extension, step back and normalise the data, the existing tables. Then the extension will be much easier, and you will end up with less tables.
if you provide info re the tables (Person, Trip, Package, etc); what exactly is a Registration, etc ... I can provide more explicit answers.
Generally any attribute that is 1::1 with the PK of an Entity should be an attribute in that entity. Any attribute that is 1::0-1 with the PK of an Entity should be in a separate table.
ER Diagram
Based on the information provided, this is your ▶Entity Relation Diagram◀. As long as you use Relational Identifiers, all the Relations you have identified thus far are supported directly (otherwise, if you use IDs, you will need more Relations and tables).
Readers who are unfamiliar with the Relational Database Modelling standard may find ▶IDEF1X Notation◀ useful.
What is the real difference between one-to-many and many-to-one relationship? It is only reversed, kind of?
I can't find any 'good-and-easy-to-understand' tutorial about this topic other than this one: SQL for Beginners: Part 3 - Database Relationships
Yes, it is vice versa. It depends on which side of the relationship the entity is present on.
For example, if one department can employ several employees then department to employee is a one-to-many relationship (1 department employs many employees), while employee to department relationship is many-to-one (many employees work in one department).
More info on the relationship types:
Database Relationships - IBM DB2 documentation
From this page about Database Terminology
Most relations between tables are one-to-many.
Example:
One area can be the habitat of many readers.
One reader can have many subscriptions.
One newspaper can have many subscriptions.
A Many to One relation is the same as one-to-many, but from a different viewpoint.
Many readers live in one area.
Many subscriptions can be of one and the same reader.
Many subscriptions are for one and the same newspaper.
What is the real difference between one-to-many and many-to-one relationship?
There are conceptual differences between these terms that should help you visualize the data and also possible differences in the generated schema that should be fully understood. Mostly the difference is one of perspective though.
In a one-to-many relationship, the local table has one row that may be associated with many rows in another table. In the example from SQL for beginners, one Customer may be associated to many Orders.
In the opposite many-to-one relationship, the local table may have many rows that are associated with one row in another table. In our example, many Orders may be associated to one Customer. This conceptual difference is important for mental representation.
In addition, the schema which supports the relationship may be represented differently in the Customer and Order tables. For example, if the customer has columns id and name:
id,name
1,Bill Smith
2,Jim Kenshaw
Then for a Order to be associated with a Customer, many SQL implementations add to the Order table a column which stores the id of the associated Customer (in this schema customer_id:
id,date,amount,customer_id
10,20160620,12.34,1
11,20160620,7.58,1
12,20160621,158.01,2
In the above data rows, if we look at the customer_id id column, we see that Bill Smith (customer-id #1) has 2 orders associated with him: one for $12.34 and one for $7.58. Jim Kenshaw (customer-id #2) has only 1 order for $158.01.
What is important to realize is that typically the one-to-many relationship doesn't actually add any columns to the table that is the "one". The Customer has no extra columns which describe the relationship with Order. In fact the Customer might also have a one-to-many relationship with ShippingAddress and SalesCall tables and yet have no additional columns added to the Customer table.
However, for a many-to-one relationship to be described, often an id column is added to the "many" table which is a foreign-key to the "one" table -- in this case a customer_id column is added to the Order. To associated order #10 for $12.34 to Bill Smith, we assign the customer_id column to Bill Smith's id 1.
However, it is also possible for there to be another table that describes the Customer and Order relationship, so that no additional fields need to be added to the Order table. Instead of adding a customer_id field to the Order table, there could be Customer_Order table that contains keys for both the Customer and Order.
customer_id,order_id
1,10
1,11
2,12
In this case, the one-to-many and many-to-one is all conceptual since there are no schema changes between them. Which mechanism depends on your schema and SQL implementation.
Hope this helps.
SQL
In SQL, there is only one kind of relationship, it is called a Reference. (Your front end may do helpful or confusing things [such as in some of the Answers], but that is a different story.)
A Foreign Key in one table (the referencing table)
References
a Primary Key in another table (the referenced table)
In SQL terms, Bar references Foo
Not the other way around
CREATE TABLE Foo (
Foo CHAR(10) NOT NULL, -- primary key
Name CHAR(30) NOT NULL
CONSTRAINT PK -- constraint name
PRIMARY KEY (Foo) -- pk
)
CREATE TABLE Bar (
Bar CHAR(10) NOT NULL, -- primary key
Foo CHAR(10) NOT NULL, -- foreign key to Foo
Name CHAR(30) NOT NULL
CONSTRAINT PK -- constraint name
PRIMARY KEY (Bar), -- pk
CONSTRAINT Foo_HasMany_Bars -- constraint name
FOREIGN KEY (Foo) -- fk in (this) referencing table
REFERENCES Foo(Foo) -- pk in referenced table
)
Since Foo.Foo is a Primary Key, it is unique, there is only one row for any given value of Foo
Since Bar.Foo is a Reference, a Foreign Key, and there is no unique index on it, there can be many rows for any given value of Foo
Therefore the relation Foo::Bar is one-to-many
Now you can perceive (look at) the relation the other way around, Bar::Foo is many-to-one
But do not let that confuse you: for any one Bar row, there is just one Foo row that it References
In SQL, that is all we have. That is all that is necessary.
What is the real difference between one to many and many to one relationship?
There is only one relation, therefore there is no difference. Perception (from one "end" or the other "end") or reading it backwards, does not change the relation.
Cardinality
Cardinality is declared first in the data model, which means Logical and Physical (the intent), and then in the implementation (the intent realised).
One to zero-to-many
In SQL that (the above) is all that is required.
One to one-to-many
You need a Transaction to enforce the one in the Referencing table.
One to zero-to-one
You need in Bar:
CONSTRAINT AK -- constraint name
UNIQUE (Foo) -- unique column, which makes it an Alternate Key
One to one
You need a Transaction to enforce the one in the Referencing table.
Many-to-Many
There is no such thing at the Physical level (recall, there is only one type of relation in SQL).
At the early Logical levels during the modelling exercise, it is convenient to draw such a relation. Before the model gets close to implementation, it had better be elevated to using only things that can exist. Such a relation is resolved by implementing an Associative Table at the physical [DDL] level.
There is no difference. It's just a matter of language and preference as to which way round you state the relationship.
Answer to your first question is : both are similar,
Answer to your second question is: one-to-many --> a MAN(MAN table) may have more than one wife(WOMEN table) many-to-one --> more than one women have married one MAN.
Now if you want to relate this relation with two tables MAN and WOMEN, one MAN table row may have many relations with rows in the WOMEN table. hope it clear.
One-to-Many and Many-to-One are similar in Multiplicity but not Aspect (i.e. Directionality).
The mapping of Associations between entity classes and the Relationships between tables. There are two categories of Relationships:
Multiplicity (ER term: cardinality)
One-to-one relationships (abbreviated 1:1): Example Husband and Wife
One-to-Many relationships (abbreviated 1:N): Example Mother and Children
Many-to-Many relationships (abbreviated M:N): Example Student and Subject
Directionality : Not affect on mapping but makes difference on how we can access data.
Uni-directional relationships: A relationship field or property that refers to the other entity.
Bi-directional relationships: Each entity has a relationship field or property that refers to the other entity.
This is an excellent question, according to my experience, in ERD diagrams and relational databases direction is implied. In RDBMS you always define Many-To->One (trivial case One-To->One) relationships. The Many side of the relationship, a.k.a children, references the One side, a.k.a parent and you implement this with a Foreign Key constraint. Technically speaking you have to access an index, fetch the Primary Key record of the One side and then visit this record to get more information.
You cannot do this the other way around unless we are speaking about Object-Relational DBMS such as Postgres, Intersystems Cache, etc. These DBMS allow you to define a bi-directional relationship between the two entities (tables). In that case accessing records the other way around, i.e. One--To-->Many is achieved by using an array of references (children). In ORMs you have classes that reference each other the same way we described here.
WARNING: Most RDBMS in the IT market are NOT relational database management systems in the strict sense, think about null values, duplicate records etc, many of these allowed features break the definition of what a Relation is.
There's no practical difference. Just use the relationship which makes the most sense given the way you see your problem as Devendra illustrated.
One-to-many and Many-to-one relationship is talking about the same logical relationship, eg an Owner may have many Homes, but a Home can only have one Owner.
So in this example Owner is the One, and Homes are the Many.
Each Home always has an owner_id (eg the Foreign Key) as an extra column.
The difference in implementation between these two, is which table defines the relationship.
In One-to-Many, the Owner is where the relationship is defined. Eg, owner1.homes lists all the homes with owner1's owner_id
In Many-to-One, the Home is where the relationship is defined. Eg, home1.owner lists owner1's owner_id.
I dont actually know in what instance you would implement the many-to-one arrangement, because it seems a bit redundant as you already know the owner_id. Perhaps its related to cleanness of deletions and changes.
---One to Many--- A Parent can have two or more children.
---Many to one--- Those 3 children can have a single Parent
Both are similar. This can be used according to the need. If you want to find children for a particular parent, then you can go with One-To-Many. Or else, want to find parents for twins, you may go with Many-To-One.
The easiest explanation I can give for this relationship is by piggybacking on evendra D. Chavan'sanswer.
Using the department and employee relationship
A department can have multiple employees, so from the employee side, it's one-to-many relationship, and from the department side it's many-to-one relationship
But if an employee can also belong to more than one department, we can also say from the employee side it's now many as opposed to one, so the relationship becomes many-to-many
In order words, a simple understanding would be, we can state that a relationship is many-to-many if one-to-many can be viewed from both sides
that is if;
one employee can belong to many departments (one-to-many)
one department can have many employees (one-to-many)
I am new to SQL and only have experience using SQLAlchemy. The documentation on relationships in SQLAlchemy does a good job explaining this, in my opinion.
You may find some clarity by reading this part
Also, I had to come up with my own example to think through this. I'll try to explain without writing a bunch of code for simplicity.
table Vehicle
column (name)
table Manufacturer
column (name)
A Vehicle can only have One manufacturer (Ford, Tesla, BMW etc.)
Manufacturers can make many Vehicles
Ford
Ford makes Mustang
Ford makes F-150
Ford makes Focus
Tesla
Tesla makes Model S
Tesla makes Model X
Tesla makes Roadster
When looking at the database rows you will want to decide if you want a column that references the other side of the relationship. This is where the SQLAlchemy documentation brings in the difference between backref vs. back_populates. I understand that is the difference between having a column in the table to reference the other side of the relationship or not having a column to reference the other side.
I hope this helps, and even more so, I hope I am accurate in the way I learned and understand this.
I have read most of the answer. The problem is not the relationship here at all. If you look at One to Many or Many to One conceptually, it is just a reversible relationship. HOWEVER, while implementing the concept in your software or application it differs a lot.
In case of Many to One, we often desire the table that has Many aspect to be written first and we desire it to associate with the table containing One aspect. If you convert Many to One concept into One to Many, you will have hard time writing the One aspect table first in your code. Since, the relationship is defined while you engineer the database, Many aspect table will seek for the One aspect table data for integrity. So if you are planning to do it by using foreign key -> unique key or foreign key -> primary key, Many to One implementation will be different even if you consider it as a One to Many.
I personally make associations without using actual relationship concepts in many cases. There is no such boundaries as to use Database concept to form relationship every time. Just make sure that your database integrity is maintained as you want, it is indexed properly for your search needs and is decently normalized.
one-to-many has parent class contains n number of childrens so it is a collection mapping.
many-to-one has n number of childrens contains one parent so it is a object mapping
I was thinking the other day on normalization, and it occurred to me, I cannot think of a time where there should be a 1:1 relationship in a database.
Name:SSN? I'd have them in the same table.
PersonID:AddressID? Again, same table.
I can come up with a zillion examples of 1:many or many:many (with appropriate intermediate tables), but never a 1:1.
Am I missing something obvious?
A 1:1 relationship typically indicates that you have partitioned a larger entity for some reason. Often it is because of performance reasons in the physical schema, but it can happen in the logic side as well if a large chunk of the data is expected to be "unknown" at the same time (in which case you have a 1:0 or 1:1, but no more).
As an example of a logical partition: you have data about an employee, but there is a larger set of data that needs to be collected, if and only if they select to have health coverage. I would keep the demographic data regarding health coverage in a different table to both give easier security partitioning and to avoid hauling that data around in queries unrelated to insurance.
An example of a physical partition would be the same data being hosted on multiple servers. I may keep the health coverage demographic data in another state (where the HR office is, for example) and the primary database may only link to it via a linked server... avoiding replicating sensitive data to other locations, yet making it available for (assuming here rare) queries that need it.
Physical partitioning can be useful whenever you have queries that need consistent subsets of a larger entity.
One reason is database efficiency. Having a 1:1 relationship allows you to split up the fields which will be affected during a row/table lock. If table A has a ton of updates and table b has a ton of reads (or has a ton of updates from another application), then table A's locking won't affect what's going on in table B.
Others bring up a good point. Security can also be a good reason depending on how applications etc. are hitting the system. I would tend to take a different approach, but it can be an easy way of restricting access to certain data. It's really easy to just deny access to a certain table in a pinch.
My blog entry about it.
Sparseness. The data relationship may be technically 1:1, but corresponding rows don't have to exist for every row. So if you have twenty million rows and there's some set of values that only exists for 0.5% of them, the space savings are vast if you push those columns out into a table that can be sparsely populated.
Most of the highly-ranked answers give very useful database tuning and optimization reasons for 1:1 relationships, but I want to focus on nothing but "in the wild" examples where 1:1 relationships naturally occur.
Please note one important characteristic of the database implementation of most of these examples: no historical information is retained about the 1:1 relationship. That is, these relationships are 1:1 at any given point in time. If the database designer wants to record changes in the relationship participants over time, then the relationships become 1:M or M:M; they lose their 1:1 nature. With that understood, here goes:
"Is-A" or supertype/subtype or inheritance/classification relationships: This category is when one entity is a specific type of another entity. For example, there could be an Employee entity with attributes that apply to all employees, and then different entities to indicate specific types of employee with attributes unique to that employee type, e.g. Doctor, Accountant, Pilot, etc. This design avoids multiple nulls since many employees would not have the specialized attributes of a specific subtype. Other examples in this category could be Product as supertype, and ManufacturingProduct and MaintenanceSupply as subtypes; Animal as supertype and Dog and Cat as subtypes; etc. Note that whenever you try to map an object-oriented inheritance hierarchy into a relational database (such as in an object-relational model), this is the kind of relationship that represents such scenarios.
"Boss" relationships, such as manager, chairperson, president, etc., where an organizational unit can have only one boss, and one person can be boss of only one organizational unit. If those rules apply, then you have a 1:1 relationship, such as one manager of a department, one CEO of a company, etc. "Boss" relationships don't only apply to people. The same kind of relationship occurs if there is only one store as the headquarters of a company, or if only one city is the capital of a country, for example.
Some kinds of scarce resource allocation, e.g. one employee can be assigned only one company car at a time (e.g. one truck per trucker, one taxi per cab driver, etc.). A colleague gave me this example recently.
Marriage (at least in legal jurisdictions where polygamy is illegal): one person can be married to only one other person at a time. I got this example from a textbook that used this as an example of a 1:1 unary relationship when a company records marriages between its employees.
Matching reservations: when a unique reservation is made and then fulfilled as two separate entities. For example, a car rental system might record a reservation in one entity, and then an actual rental in a separate entity. Although such a situation could alternatively be designed as one entity, it might make sense to separate the entities since not all reservations are fulfilled, and not all rentals require reservations, and both situations are very common.
I repeat the caveat I made earlier that most of these are 1:1 relationships only if no historical information is recorded. So, if an employee changes their role in an organization, or a manager takes responsibility of a different department, or an employee is reassigned a vehicle, or someone is widowed and remarries, then the relationship participants can change. If the database does not store any previous history about these 1:1 relationships, then they remain legitimate 1:1 relationships. But if the database records historical information (such as adding start and end dates for each relationship), then they pretty much all turn into M:M relationships.
There are two notable exceptions to the historical note: First, some relationships change so rarely that historical information would normally not be stored. For example, most IS-A relationships (e.g. product type) are immutable; that is, they can never change. Thus, the historical record point is moot; these would always be implemented as natural 1:1 relationships. Second, the reservation-rental relationship store dates separately, since the reservation and the rental are independent events, each with their own dates. Since the entities have their own dates, rather than the 1:1 relationship itself having a start date, these would remain as 1:1 relationships even though historical information is stored.
Your question can be interpreted in several ways, because of the way you worded it. The responses show this.
There can definitely be 1:1 relationships between data items in the real world. No question about it. The "is a" relationship is generally one to one. A car is a vehicle.
One car is one vehicle. One vehicle might be one car. Some vehicles are trucks, in which case one vehicle is not a car. Several answers address this interpretation.
But I think what you really are asking is... when 1:1 relationships exist, should tables ever be split? In other words, should you ever have two tables that contain exactly the same keys? In practice, most of us analyze only primary keys, and not other candidate keys, but that question is slightly diferent.
Normalization rules for 1NF, 2NF, and 3NF never require decomposing (splitting) a table into two tables with the same primary key. I haven't worked out whether putting a schema in BCNF, 4NF, or 5NF can ever result in two tables with the same keys. Off the top of my head, I'm going to guess that the answer is no.
There is a level of normalization called 6NF. The normalization rule for 6NF can definitely result in two tables with the same primary key. 6NF has the advantage over 5NF that NULLS can be completely avoided. This is important to some, but not all, database designers. I've never bothered to put a schema into 6NF.
In 6NF missing data can be represent by an omitted row, instead of a row with a NULL in some column.
There are reasons other than normalization for splitting tables. Sometimes split tables result in better performance. With some database engines, you can get the same performance benefits by partitioning the table instead of actually splitting it. This can have the advantage of keeping the logical design easy to understand, while giving the database engine the tools needed to speed things up.
I use them primarily for a few reasons. One is significant difference in rate of data change. Some of my tables may have audit trails where I track previous versions of records, if I only care to track previous versions of 5 out of 10 columns splitting those 5 columns onto a separate table with an audit trail mechanism on it is more efficient. Also, I may have records (say for an accounting app) that are write only. You can not change the dollar amounts, or the account they were for, if you made a mistake then you need to make a corresponding record to write adjust off the incorrect record, then create a correction entry. I have constraints on the table enforcing the fact that they cannot be updated or deleted, but I may have a couple of attributes for that object that are malleable, those are kept in a separate table without the restriction on modification. Another time I do this is in medical record applications. There is data related to a visit that cannot be changed once it is signed off on, and other data related to a visit that can be changed after signoff. In that case I will split the data and put a trigger on the locked table rejecting updates to the locked table when signed off, but allowing updates to the data the doctor is not signing off on.
Another poster commented on 1:1 not being normalized, I would disagree with that in some situations, especially subtyping. Say I have an employee table and the primary key is their SSN (it's an example, let's save the debate on whether this is a good key or not for another thread). The employees can be of different types, say temporary or permanent and if they are permanent they have more fields to be filled out, like office phone number, which should only be not null if the type = 'Permanent'. In a 3rd normal form database the column should depend only on the key, meaning the employee, but it actually depends on employee and type, so a 1:1 relationship is perfectly normal, and desirable in this case. It also prevents overly sparse tables, if I have 10 columns that are normally filled, but 20 additional columns only for certain types.
The most common scenario I can think of is when you have BLOB's. Let's say you want to store large images in a database (typically, not the best way to store them, but sometimes the constraints make it more convenient). You would typically want the blob to be in a separate table to improve lookups of the non-blob data.
In terms of pure science, yes, they are useless.
In real databases it's sometimes useful to keep a rarely used field in a separate table: to speed up queries using this and only this field; to avoid locks, etc.
Rather than using views to restrict access to fields, it sometimes makes sense to keep restricted fields in a separate table to which only certain users have access.
I can also think of situations where you have an OO model in which you use inheritance, and the inheritance tree has to be persisted to the DB.
For instance, you have a class Bird and Fish which both inherit from Animal.
In your DB you could have an 'Animal' table, which contains the common fields of the Animal class, and the Animal table has a one-to-one relationship with the Bird table, and a one-to-one relationship with the Fish table.
In this case, you don't have to have one Animal table which contains a lot of nullable columns to hold the Bird and Fish-properties, where all columns that contain Fish-data are set to NULL when the record represents a bird.
Instead, you have a record in the Birds-table that has a one-to-one relationship with the record in the Animal table.
1-1 relationships are also necessary if you have too much information. There is a record size limitation on each record in the table. Sometimes tables are split in two (with the most commonly queried information in the main table) just so that the record size will not be too large. Databases are also more efficient in querying if the tables are narrow.
In SQL it is impossible to enforce a 1:1 relationship between two tables that is mandatory on both sides (unless the tables are read-only). For most practical purposes a "1:1" relationship in SQL really means 1:0|1.
The inability to support mandatory cardinality in referential constraints is one of SQL's serious limitations. "Deferrable" constraints don't really count because they are just a way of saying the constraint is not enforced some of the time.
It's also a way to extend a table which is already in production with less (perceived) risk than a "real" database change. Seeing a 1:1 relationship in a legacy system is often a good indicator that fields were added after the initial design.
Most of the time, designs are thought to be 1:1 until someone asks "well, why can't it be 1:many"? Divorcing the concepts from one another prematurely is done in anticipation of this common scenario. Person and Address don't bind so tightly. A lot of people have multiple addresses. And so on...
Usually two separate object spaces imply that one or both can be multiplied (x:many). If two objects were truly, truly 1:1, even philosophically, then it's more of an is-relationship. These two "objects" are actually parts of one whole object.
If you're using the data with one of the popular ORMs, you might want to break up a table into multiple tables to match your Object Hierarchy.
I have found that when I do a 1:1 relationship its totally for a systemic reason, not a relational reason.
For instance, I've found that putting the reserved aspects of a user in 1 table and putting the user editable fields of the user in a different table allows logically writing those rules about permissions on those fields much much easier.
But you are correct, in theory, 1:1 relationships are completely contrived, and are almost a phenomenon. However logically it allows the programs and optimizations abstracting the database easier.
extended information that is only needed in certain scenarios. in legacy applications and programming languages (such as RPG) where the programs are compiled over the tables (so if the table changes you have to recompile the program(s)). Tag along files can also be useful in cases where you have to worry about table size.
Most frequently it is more of a physical than logical construction. It is commonly used to vertically partition a table to take advantage of splitting I/O across physical devices or other query optimizations associated with segregating less frequently accessed data or data that needs to be kept more secure than the rest of the attributes on the same object (SSN, Salary, etc).
The only logical consideration that prescribes a 1-1 relationship is when certain attributes only apply to some of the entities. However, in most cases there is a better/more normalized way to model the data through entity extraction.
The best reason I can see for a 1:1 relationship is a SuperType SubType of database design. I created a Real Estate MLS data structure based on this model. There were five different data feeds; Residential, Commercial, MultiFamily, Hotels & Land.
I created a SuperType called property that contained data that was common to each of the five separate data feeds. This allowed for very fast "simple" searches across all datatypes.
I create five separate SubTypes that stored the unique data elements for each of the five data feeds. Each SuperType record had a 1:1 relationship to the appropriate SubType record.
If a customer wanted a detailed search they had to select a Super-Sub type for example PropertyResidential.
In my opinion a 1:1 relationship maps a class Inheritance on a RDBMS.
There is a table A that contains the common attributes, i.e. the partent class status
Each inherited class status is mapped on the RDBMS with a table B with a 1:1 relationship
to A table, containing the specialized attributes.
The table namend A contain also a "type" field that represents the "casting" functionality
Bye
Mario
You can create a one to one relationship table if there is any significant performance benefit. You can put the rarely used fields into separate table.
1:1 relationships don't really make sense if you're into normalization as anything that would be 1:1 would be kept in the same table.
In the real world though, it's often different. You may want to break your data up to match your applications interface.
Possibly if you have some kind of typed objects in your database.
Say in a table, T1, you have the columns C1, C2, C3… with a one to one relation. It's OK, it's in normalized form. Now say in a table T2, you have columns C1, C2, C3, … (the names may differ, but say the types and the role is the same) with a one to one relation too. It's OK for T2 for the same reasons as with T1.
In this case however, I see a fit for a separate table T3, holding C1, C2, C3… and a one to one relation from T1 to T3 and from T2 to T3. I even more see a fit if there exist another table, with which there already exist a one to multiple C1, C2, C3… say from table A to multiple rows in table B. Then, instead of T3, you use B, and have a one to one relation from T1 to B, the same for from T2 to B, and still the same one to multiple relation from A to B.
I believe normalization do not agree with this, and that may be an idea outside of it: identifying object types and move objects of a same type to their own storage pool, using a one to one relation from some tables, and a one to multiple relation from some other tables.
It is unnecessary great for security purposes but there better ways to perform security checks. Imagine, you create a key that can only open one door. If the key can open any other door, you should ring the alarm. In essence, you can have "CitizenTable" and "VotingTable". Citizen One vote for Candidate One which is stored in the Voting Table. If citizen one appear in the voting table again, then their should be an alarm. Be advice, this is a one to one relationship because we not refering to the candidate field, we are refering to the voting table and the citizen table.
Example:
Citizen Table
id = 1, citizen_name = "EvryBod"
id = 2, citizen_name = "Lesly"
id = 3, citizen_name = "Wasserman"
Candidate Table
id = 1, citizen_id = 1, candidate_name = "Bern Nie"
id = 2, citizen_id = 2, candidate_name = "Bern Nie"
id = 3, citizen_id = 3, candidate_name = "Hill Arry"
Then, if we see the voting table as so:
Voting Table
id = 1, citizen_id = 1, candidate_name = "Bern Nie"
id = 2, citizen_id = 2, candidate_name = "Bern Nie"
id = 3, citizen_id = 3, candidate_name = "Hill Arry"
id = 4, citizen_id = 3, candidate_name = "Hill Arry"
id = 5, citizen_id = 3, candidate_name = "Hill Arry"
We could say that citizen number 3 is a liar pants on fire who cheated Bern Nie. Just an example.
When you are dealing with a database from a third party product, then you probably don't want to alter their database as to prevent tight coupling. but you may have data that corresponds 1:1 with their data
Anywhere were two entirely independent entities share a one-to-one relationship. There must be lots of examples:
person <-> dentist (its 1:N, so its wrong!)
person <-> doctor (its 1:N, so it's also wrong!)
person <-> spouse (its 1:0|1, so its mostly wrong!)
EDIT: Yes, those were pretty bad examples, particularly if I was always looking for a 1:1, not a 0 or 1 on either side. I guess my brain was mis-firing :-)
So, I'll try again. It turns out, after a bit of thought, that the only way you can have two separate entities that must (as far as the software goes) be together all of the time is for them to exist together in higher categorization. Then, if and only if you fall into a lower decomposition, the things are and should be separate, but at the higher level they can't live without each other. Context, then is the key.
For a medical database you may want to store different information about specific regions of the body, keeping them as a separate entity. In that case, a patient has just one head, and they need to have it, or they are not a patient. (They also have one heart, and a number of other necessary single organs). If you're interested in tracking surgeries for example, then each region should be a unique separate entity.
In a production/inventory system, if you're tracking the assembly of vehicles, then you certainly want to watch the engine progress differently from the car body, yet there is a one to one relationship. A care must have an engine, and only one (or it wouldn't be a 'car' anymore). An engine belongs to only one car.
In each case you could produce the separate entities as one big record, but given the level of decomposition, that would be wrong. They are, in these specific contexts, truly independent entities, although they might not appear so at a higher level.
Paul.
I hear a lot about subtyping tables when designing a database, and I'm fully aware of the theory behind them. However, I have never actually seen table subtyping in action. How can you create subtypes of tables? I am using MS Access, and I'm looking for a way of doing it in SQL as well as through the GUI (Access 2003).
Cheers!
An easy example would be to have a Person table with a primary key and some columns in that table. Now you can create another table called Student that has a foreign key to the person table (its supertype). Now the student table has some columns which the supertype doesn't have like GPA, Major, etc. But the name, last name and such would be in the parent table. You can always access the student name back in the Person table through the foreign key in the Student table.
Anyways, just remember the following:
The hierarchy depicts relationship between supertypes and subtypes
Supertypes has common attributes
Subtypes have uniques attributes
Subtypes of tables is a conceptual thing in EER diagrams. I haven't seen an RDBMS (excluding object-relational DBMSs) that supports it directly. They are usually implemented in either
A set of nullable columns for each property of the subtype in a single table
With a table for base type properties and some other tables with at most one row per base table that will contain subtype properties
The notion of table sub-types is useful when using an ORM mapper to produce class sub-type heirarchy that exactly models the domain.
A sub-type table will have both a Foreign Key back to its parent which is also the sub-types table's primary key.
Keep in mind that in designing a bound application, as with an Access application, subtypes impose a heavy cost in terms of joins.
For instance, if you have a supertype table with three subtype tables and you need to display all three in a single form at once (and you need to show not just the supertype date), you end up with a choice of using three outer joins and Nz(), or you need a UNION ALL of three mutually exclusive SELECT statements (one for each subtype). Neither of these will be editable.
I was going to paste some SQL from the first major app where I worked with super/subtype tables, but looking at it, the SQL is so complicated it would just confuse people. That's not so much because my app was complicated, but it's because the nature of the problem is complex -- presenting the full set of data to the user, both super- and subtypes, is by its very nature complex. My conclusion from working with it was that I'd have been better off with only one subtype table.
That's not to say it's not useful in some circumstances, just that Access's bound forms don't necessarily make it easy to present this data to the user.
I have a similar problem I've been working on.
While looking for a repeatable pattern, I wanted to make sure I didn't abandon referential integrity, which meant that I wouldn't use a (TABLE_NAME, PK_ID) solution.
I finally settled on:
Base Type Table: CUSTOMER
Sub Type Tables: PERSON, BUSINESS, GOVT_ENTITY
I put nullable PRERSON_ID, BUSINESS_ID and GOVT_ENTITY_ID fields in CUSTOMER, with foreign keys on each, and a check constraint that only one is not null. It's easy to add new sub types, just need to add the nullable foreign key and modify the check constraint.