I have a database with several tables
Student
Teacher
Parents
Staff
All need to have a reference to an address table
Address
door number
street
town
city
postcode
How can I create a address table with little duplication of data? Is the only way to have separate tables for each?
Have a separate Address table with the following columns
address_id
door_number
street
town
city
state
country
postcode
Now in each of the tables - Student , Parent , Teacher , Staff - have an address_id column and create a foreign key to the address_id in the address table.
Assuming Student and Parent are already related, you can have the address just in the Parents table.
Related
I have two mysql database table. They have one-to-one relationship between each others. They are empty. I can't insert value to anyone. Each one has a foreign key of another one. I'm planning to insert value to them in the same time. But, I didn't find which sql query is necessary. What is your offer?
Thanks
one-to-one relationship example:
student: student_id, first_name, last_name, address_id
address: address_id, address, city, zipcode, student_id
For 1 to 1 table relationship, that doesn't mean you have to put their PK on each other, instead people usually decide which FK goes to another table and that's all. From what you did, that shows Many to Many table relationship, and the right schema would be creating a new table that has FK to those 2 tables.
Details:
If 1 student can have MANY address and 1 address can be lived by MANY student, then the schema is:
student: student_id, first_name, last_name, address_id
address: address_id, address, city, zipcode, student_id
student_address: student_id (FK), address_id (FK)
If 1 student can have only 1 address and 1 address can be lived only by 1 student, then the schema is:
student: student_id, first_name, last_name, address_id, address, city, zipcode
You don't need address_Id in the student table. What if the student is homeless? What if a student has more than one addresss? He/she might have a mailing address a local address in the college town, and a home address.
And even for students with only one address, you can get that address by querying the address table using student_Id.
Select * From addresses where student_id = [Whatever his/her id is]
Even more generally, multiple students might live at the same address. Neither table should have a FK to the other. There should be an address table, with addressID, a Student table with studentId, and a third table that contains just studentId and addressId to indicate the association between one student and one address. The PK for this table should be composite (using both StudentId and AddressId)
That is not how MYSQL works. It sounds like your database design needs to be reworked. You can't have a circular foreign keys like that. You can only insert into one table at a time.
Looking at your tables, the student should have Student Id as the primary key, and a foreign key relationship to the address table. The student Id in the address shouldn't be in that table.
I'm designing a table 'employees', which contains an primary key which is auto increment and represents an ID of the employee.
I want to prefix the ID with an number designating the city: city 1: 1, city 2:2, etc.
So the IDs should look like xyy where x represents the city and yy the ID of the employee.
When I'm adding new employee I'm selecting the city x, and I would like to yy values to auto increment.
Is that possible using SQL commands?
That is not good database design. You really should have a separate column for the city in your table. If you have many cities, the cities should perhaps be in their own table. What you are trying to do is overly complex and although 'everything is possible', I would not recommend it.
You are effectively packing two fields into one and violating the principle of atomicity and the 1NF in the process. On top of that, your key is not minimal (so to speak).
Instead, keep two separate fields: ID and CITY.
ID alone is the primary key. In your own words, ID is auto-increment, so it alone is unique.
You can easily concatenate ID and CITY together for display purposes in your query or VIEW or even in the client code. There is no reason to "precook" the concatenated value in the table itself.
Given this requirement from the comments, "Unique ID should provide users with an info of the city, company requirements", I would do this.
table employee would have an employeeID as the primary key. Other fields would be firstname, lastname, birthdate, gender, etc
table city would have a cityId as the primary key. Other fields would be the name of the city, provinceState, Country, whatever is appropriate.
Table EmployeeCity would have have a primary key of EmployeeId, CityId, and StartDate. Not part of the primary key would be field EndDate.
The primary key of EmployeeCity satisfies the requirement of a unique identifier which leads to city information. Also, if an employee changes cities, it's a simple matter of updating one record and adding another.
Could someone suggest the best design for the following scenario?
I have a database in which there is a table called City. This table has the following fields:
City id (Primary key)
City Name
State Id (which is linked to the State table)
My problem is I have 10 cities with the same name in one state. What will be the best design so I can represent one city name per id?
It does not matter that they have the same City Name, as long as they have different City Ids.
Just make sure to set the CityId as primary key in the City table. Also, it would be useful to make it an identity autoincrement column, so that it is inserted automatically and will always be unique.
Same goes for StateId in the State table.
Also, if you use a visual management tool for the database, make sure to set the foreign key relationship between the two tables:
FK_State.StateId_City.StateId.
Is it ok for a table to have two of the same foreign keys as columns?
I.e. I have two tables, one is Country, the other is City. In the Country table:
COUNTRY
--------------
id
name
capitalcity <--- this would have foreign key 'city_id'.
populouscity <-- this would also have a foreign key 'city_id'.
created_at
updated_at
CITY
-------
id
name
populous (bool)
capital (bool)
created_at
updated_at
Keep in mind that the capital city may or may not also be the most populous.
I have wondered if I should just seperate out the two boolean colums of city, have city as city with name only, and have a populous table that references to city, and capital that references to city too. And have two seperate foreign keys in the countries table from the two new tables?
I would go about the design this way
COUNTRY
--------------
id
name
CITY
-------
id
country_id ( useful to know what country a city is in )
name
created_at
updated_at
CAPITALS
----------
id
city_id Unique
POPULUS
-------
id
city_id Unique
Yes it's OK. People sometimes avoid such "explicit" FKs because they are not "flexible", but if you know you'll always need to relate to exactly these two cities, this is the appropriate design. In any case, you don't need these FKs and bool flags.
What I don't see is how you connect non-capital and not-most-populous cities to the country. If you're not careful about how you design your keys, you could end-up with the situation where a city can be a capital of the country it does not belong to.
Using an identifying relationship avoids this issue:
So, every city is identified by a number (CITY_NO) within its country. When the PK is migrated back from CITY to COUNTRY, the COUNTRY_ID is "merged" back to its origin, so there cannot be a country mismatch (note FK1 and FK2 on COUNTRY.COUNTRY_ID).
CAPITAL_NO and POPULOUS_NO are left NULL-able so they can temporarily remain NULL to solve the chicken-and-egg problem caused by circular FKs. This works because InnoDB enforces FKs using MATCH SIMPLE method, so it is enough for just one component of the composite FK to be NULL to avoid FK violation.
BTW, consider whether you actually need POPULOUS_ID - if you keep the population of all cities, then you can derive which one is most populous simply by finding MAX.
You can always add a surrogate key such as CITY_ID if you need it for child FKs or to pacify your ORM...
I need help designing my country, city, state tables. I will provide sample data from my table so that you can help me better on my problem.
This is my country table:
Country
______
code name
US United States
SG Singapore
GB United Kingdom
This is my city table:
City
_____
id country city state
1 US Birmingham Alabama
2 US Auburn Alabama
.
.
29 GB Cambridge NULL
30 GB Devon NULL
My problem is that the only country that has the state field is the US. All other cities have a null value.
My temporary solution for this is to just create a special city table for the United States, then all other countries have another city table that doesn't have the state field.
I think this will just complicate the matter, because I have two tables for cities.
How can I improve this design?
Why not go relational?
Country ( CountryID, CountryCode, CountryName )
Region ( RegionID, RegionCode, RegionName, CountryID )
City ( CityID, CityCode, CityName, RegionID )
The 'Region' name is a big more generic than State, which means it would likely make more sense everywhere.
Why not a standard 3-way linked table set?
table country (
id int primary key,
name varchar(255)
);
table state (
id int primary key,
name varchar(255),
country_id int foreign key country (id)
);
table city (
id int primary key,
name varchar(255)
state_id int foreign key state (id)
);
This'll hold up for most cases, except a few degenerate ones like Lloydminster, Saskatchewan, which straddles two provincial borders.
There are lots of countries besides the United States that have political divisions between the national and municipal level. Australia has states, Canada has provinces, Japan has Prefectures, and so forth.
The question is how do you track this information and keep it consistent? You could have a "dummy record" at the middle level for countries that don't have one. Another way to handle this is to denormalize foreign keys to all levels down to the entity containing the address. If country and city are mandatory then their foreign keys would be not nullable whereas your state FK could be nullable.
If you go the denormalization route, you will need application logic to ensure that your foreign keys are consistent with each other.
If you go the dummy state record route, you will need application logic to ensure that dummy layers are hidden from users in the user interface.