I'm new in programming. I'm designing a database that has two tables: Addresses and Customers. I don't know how to assign foreign keys. I don't know which way is better to use:
Method1:
Customer Table Columns:
CustomerID
FirstName
LastName
Address ID
Addresses Table Columns:
AddressId
Country
State
City
AddressLine
Method2
Customer Table:
CustomerId
FirstName
LastName
Addresses Table:
AddressId
CustomerId
Country
City
AddressLine
In other words I don't know where to place the foreign key.
If you are trying to implement one to many, so the recommended way is to put the primary key for the table besides the one into the table of the many as a foreign key..
For example: if one costumer have many addresses and address have one costumer. so you will have to put the costumerId as a foreign key in the table of the address.
if one address can have many costumers and one costumer have one address. so you will have to put the AddressNumber as a foreign key in the table of the costumers.
Good Luck
If each customer can have many addresses, then you want to use method 2 because then there can be multiple records in Addresses for each customer in Customer.
However, it seems to me like you might need a many-to-many relationship. What happens if two customers share the same address?
You can accomplish this by including a third table, e.g. CustomerAddresses that logically sits in between Customer and Addresses. This third table will hold the foreign keys from both of the other tables -- CustomerID and AddressID.
In your first method, one customer could only be associated to one address, as it has only one id referring to an address. But nothing prevents several customers from having the same address id. So this represent a many-customer-to-one-address relation. That's not what you want.
In your second method, the relation is reversed. Each address is associated to a customer, several addresses can be associated to the same customer, the is a one-customer-to-many-addresses relation.
In sql, to retrieve the addresses associated with a customer, you would do:
select * from address where customer_id = '<some customer_id>'
I will point out that you may actually have a many to many relationship. One address can have more than one customer and one customer can have more than one address. In this case you use a Join table to model the relationship that contains the addressid and the customerid and nothing else. This would have a join PK of both those fields to ensure uniqueness.
Related
Example scenario: 1 employee will only have 1 address and 1 address will only own by that 1 employee. Below are 2 options, which are correct or neither both?
More of my confusion is should I place Employee primary key into Address table or place Address primary key into Employee table?
I'm using PostgreSQL as some of you need to know which database am I using.
Option 1
Employee
EmployeeId (PK)
EmployeeName
AddressId (FK)
Address
AddressId (PK)
AddressLine1
Option 2
Employee
EmployeeId (PK)
EmployeeName
Address
AddressId (PK)
AddressLine1
EmployeeId (FK)
Does an employee have an address, or, does an address have an employee?
I would say, an employee has an address. I would think of employees as having a primary key, and employee attributes.
employee table:
employee id
employee attributes
...
Whether or not an address needs a primary key is another question. But, if you then want to give an employee an additional attribute, "address", which resides in a separate table, I would first think of adding the foreign key in the address table to indicate to which employee this address belongs:
address table:
employee id
address attributes
...
Note that now, an employee may have multiple addresses, but two employees cannot share the same address.
If you want multiple employees to share the same address, you could, for example, introduce a primary key in the address table, and use an intermediate table:
address table:
address id
address attributes
...
employee_address table:
employee id
address id
In this case, both fields in the employee_address table are foreign keys. It would not make sense that these would be primary keys. Here, I think you would agree, the primary keys are in the employee and address tables.
To your original question then, I would naturally put the employee primary key into the address table, to show that an address belongs to an employee. But, it might not be as simple as that. You have to consider the use cases, such as whether or not two employees share the same address, and whether or not employees can have multiple addresses. Or, could employees not have an address, or, could an address not have any employees?
You don't mention the specific database, so this answer assumes it implements constraint deferrability.
If you are absolutely sure the relationship is one to one, then one of the cleanest solutions is to share the primary key value and ensure you establish two symmetric foreign keys (from employee to address, and from address to employee).
Employee
EmployeeId (PK) (FK)
EmployeeName
Address
AddressId (PK) (FK)
AddressLine1
In order to insert, update, or modify data, both FKs must be made deferrable. Deferrablity is a standard SQL feature that I know at least PostgreSQL and Oracle implement.
If you want to go a step further, the name of the PK in the address table can be EmployeeId instead of AddressId, to emphasize it's one and the same.
For one to one relationship there is no reason to have multiple tables. Add address and AddressLine1 column into Employee table as below.
Employee
EmployeeId (PK)
EmployeeName
Address
AddressLine1
This will simplify your and ui design. And one to one relationship will be forced to be maintained without any constraint.
Lets say I have a database with 4 types of things in it: Neighborhood, City, Houses, and Comment, like so
City:
name
ID
Neighborhood:
name
ID
CityID (foreign key to City:ID)
House:
name
ID
NeighborhoodID (foreign key to Neighborhood:ID)
CityID (foreign key to City:ID)
Comment:
ID
Text
???? (key to the subject of the comment)
I want users to be able to comment on a City, a Neighborhood or a House. How do I express this relationship in SQL?
One idea I had was to create 3 one to many relationship tables:
CommentToCity:
commentID
cityID
then when fetching the list of Cities, I could do a join on this table as well to get the related comments. I would then create a similar situation for House and Neighborhood.
Another idea would be to have globally unique identifiers in City, House and Neighborhood, and then have that global ID be the foreign key in the comment. Then when fetching the City it would do a join on comments looking for that global ID.
Are either of these a good way? Is there a better way?
Add a commentID to City, Neighborhood And House. (foreign key to comment:Id)
This way you just create an empty comment and add its Id if there is no comment on something.
I have a major problem with my SQL design.
I need to create a database which models the following situation:
I have a list of capitals, it looks like this: Berlin, London, Prague, you get it. The other list is a list of travellers: John, Kyle, Peter etc.
The database needs to be able to answer queries such as: List of cities a given Traveller has visited, what Travellers has visited a given City and so on.
My problem is that when I create the two tables I just freeze and am unable to figure out the connection between them that would allow me to implement the intended behaviour.
I read up on it on the internet and I was told to use intersection entities, which I can, but I just don't see how that would help me. Sorry if this is a FAQ, but I just could not get my head around the proper keywords for a search.
Isn't it easier to create third table like travelers_cities with to foreign keys traveler and city, than you jan join that table with table you need and look for result there?
Solution:
Follow the following schema
First Table: Capital
Let say two columns: cid (Primary Key), Name
Second Table: Travellers
Let say two columns: tid (Primary Key), Traveller_Name
Now there is a many to many relationship that one traveller can travel/visit one or many capitals and one capital can be visited by one or many visitors.
Many to many relationship can be acheived by creating a new table which will act as reference/mapping table. let say "capital_travellers"
So, This third table will have following columns
capital_travellers:
id (Primary key): Its optional
cid (Primary key of Capital Table will work as Foreign key)
tid (Primary key of traveller Table will work as Foreign key)
Now when you want to fetch records, you will look into this table(capital_travellers).
I hope it helps.
In a many to many relationship it is necessary to implement a third junction table between the two entities. We could, say, name it travel. This table uses two foreign keys, one from each entity, to form one compound key.
Now you have 3 tables. One table called 'Traveller', one called called 'City' and a third junction table called 'Travel'. Lets assume the primary key for traveller is travellerId and for city it's cityId. The junction table takes these two keys to form a primary key for the entity 'Travel'. When u query the database for which cities a traveller with travelId '031' has travelled to it would make use of this junction table and return the cityId's to you.
If this doesn't help or if you need more clarification I recommend searching these terms:
Many-to-many
Cardinality
I got a Person table, each Person can visit several countries. The countries visited by each Person is stored in table CountryVisit
Person:
PersonId,
Name
CountryVisit:
CountryVisitId (primary key)
PersonId (foreign key to 'Person.PersonId')
CountryName
VisitDate
For the CountryVisit Table, my primary key is CountryVisitId which is an identity column. This design will result in that a Person can have only 1 CountryVisit but the CountryVisitId can be 40 for example. Is it a better practice to create another surrogate key column to act as an identity column while the CountryVisitId be a natural key that is unique for each PersonId ?
It is pretty good. I would suggest that you have a separate table for countries, with one row per country. Then the CountryVisits table would have:
CountryVisitId PrimaryKey,
PersonId ForeignKey,
CountryId ForeignKey,
VisitDate
This will ensure that the country name is always spelled correctly and consistently. If you want a list of countries to get started, check out this Wikipedia page. Also note that your definition of country may be different from the standard list of countries (there are actually several out there), so you should use your own auto-incremented primary key, rather than using the country code.
And, you should relax the requirement and remove the unique or primary key on PersonId, CountryId, unless you want to enforce only one visit per country.
Imagine I have three tables, called "customers", "companies" and "phone_numbers". Both customers and companies can have multiple phone numbers. What would be the best way to index phone_numbers? Have both customer_id and company_id and keep one of them null? What if there are more than two tables with a one-to-many relationship with phone_numbers?
Your business rules might only state one-to-many, but in reality people & companies can be a many-to-many relationship. One person can have many phone numbers (home, cell, etc), and a phone number can relate to many people (myself, my significant other, etc). Likewise, a company number and my business number can be the same - you just use an extension number to reach me directly.
Indexing the foreign keys would be a good idea, but beware of premature optimization. Depending on setup, I'd consider a unique constraint on the phone number column but I would not have the phone number column itself as a primary key.
I would go with identity columns in the customer and company tables, then in the phone number table do as you said and keep one null and the other populated. I do something similar to this and it works out fine as long as you validate data so that it doesn't go in with both values being null. For a more elegant solution you could have two columns: one that is an id, and another that is a type identifier. Say 1 for customers and 2 for companies, that way you don't have to worry about null data or a lot of extra columns.
I'd add two columns to the phone_numbers table. The first would be an index that tells you what table to associate with (say, 1 = customers and 2 = companies). The second would be the foreign key to the appropriate table.
This way you can add as many phone number sources as you want.
If a particular person or company has more than one phone number, there would be multiple rows in the phone_numbers table.
The closest thing I have to a pattern is the following -- any two entities with a many-to-many relationship require an associative entity (a cross-reference table) between them, like so (surrogate keys assumed):
CREATE TABLE CUSTOMER_XREF_PHONE
( CUSTOMER_ID NUMBER NOT NULL,
PHONE_NUMBER_ID NUMBER NOT NULL,
CONSTRAINT CUSTOMER_XREF_PHONE_PK
PRIMARY KEY (CUSTOMER_ID, PHONE_NUMBER_ID),
CONSTRAINT CUSTOMER_XREF_PHONE_UK
UNIQUE (PHONE_NUMBER_ID, CUSTOMER_ID),
CONSTRAINT CUSTOMER_XREF_PHONE_FK01
FOREIGN KEY (CUSTOMER_ID)
REFERENCES CUSTOMER (CUSTOMER_ID) ON DELETE CASCADE,
CONSTRAINT CUSTOMER_XREF_PHONE_FK02
FOREIGN_KEY (PHONE_NUMBER_ID)
REFERENCES PHONE_NUMBERS (PHONE_NUMBER_ID) ON DELETE CASCADE
);
Such an implementation pattern can:
Be fully protected by database-level referential integrity constraints
Support bi-directional access (sometimes you need to see who else has that phone number)
Be self-cleaning if your database supports ON DELETE CASCADE
Be extended through the use of a "relationship type" attribute to map multiple independent relationships between the entities,
such as:
customer has a home telephone number
customer has a daytime telephone number
customer has a fax telephone number
customer has a mobile telephone number