Autoincrement ID with a prefix - mysql

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.

Related

database table design and relationship complexity

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.

Normalization of data for database?

Here is the data I have to normalize:
//
1NF
Customer ID [First Name (PK), Last Name (PK), Phone, Address, Town, Postcode, Email]
Booking [Date (PK), Room (PK), Type, Occupants, Nights, Arrival Time]
ExtraID [Item Name, Item Cost, Date (FK), Room (FK)]
//
First Name + Last Name = Composite Key
Date + Room = Composite Key
//
Is this ok?
Also to go into 2NF I have to identify partial dependencies. As far as I see Phone, Address, Town, Postcode and email requires both parts of the composite key?
So is this in 2NF already?
Thank you.
It's generally a good idea to use synthetic keys. This has to do with people, especially---none of the natural keys are truly fit for the primary key purpose (we might go into biometrics here but this would be a bit off topic).
So, there would need to be a table of customers with its own customers_pk primary key which could be either a sequence in the RDBMS or, say, GUID (http://en.wikipedia.org/wiki/Globally_unique_identifier).
There should be a historical table for rooms---the rates tend to change, as well as other room's characteristics. We could define a room to be unique physical object and also decide on whether a room stays the same after remodelling (there are pros and contras to that, it would depend on the business standpoint).
I would create a separate dictionary for the extras (we could use receipt IDs in there and CDR's references) and then link the extras with the bookings via a table with it's own primary key, foreign key to booking's primary key and the foreign key to extra's primary key.
Now, bookings' table should have it's own primary key, then customer's key, rooms' key, dates (they could be date type or we could create a separate time dimension where we could list various useful information such as whether it's high season or if there are some local events), number of occupants, sum of extras charges (well, might be not the best of all ideas) and the grant total.
You could use a separate sequence for each table's keys or just one for all of them---the latter is a bit more elegant.

MySQL Create pivot table from existing column in existing table

I've got a prexisting table that contains all kinds of customer information. Currently it also has the "city" as well as the "region" and the "state" listed in a 3 columns as strings. Redundant info!
I'd like to create three new tables, one for the city and one for the region and one for the state, that will contain single entries for each of the cities etc, and then reference the ID back into the existing customer table with a location_id.
How would I go about exporting the distinct city names into the cities table, and the distinct regions into a regions table, and then have the cities reference the region_id and state_id table as well so that the information is all grouped!
Amatuer question for sure, but I appreciate any help!
You don't want three different tables! You want one table with three columns: city, state, region.
The reason is that city does not exist by itself. Consider (in the US) Springfield, IL. And Springfield, MA. Or Miami, FL and Miami, OH. What you have is a dimension of the data that has hierarchies. The right way to store this is at the lowest level (city in your case) with a "dimension" table providing the other information.
Assuming that your original data is correct, you can do something like this:
create table Cities (
CityId int auto_increment not null primary key,
City varchar(255),
State varchar(255),
Region varchar(255)
);
insert into Cities(City, State, Region)
select distinct City, State, Region
from YourTable;
I realize that this is not "standard normal form". But for most applications this works well. If you are doing this for an application where you want to pick states from a list, for instance, create an index on state and the query will be fast.
There are some circumstances where you might want separate tables at the state and region level. This would be the case if you had lots of different columns at those levels. And, in particular, if you were modifying the values in those columns. A flattened dimension (such as described here) is most appropriate when the data is static (cities don't change states very often). Normalization is most appropriate when you are changing values in the different levels.

mysql/RoR database design

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...

DB schema for a booking system of fitness class

I need a schema for fitness class.
The booking system needs to store max-number of students it can take, number of students who booked to join the class, students ids, datetime etc.
A student table needs to store classes which he/she booked. But this may not need if I store students ids in class tables.
I am hoping to get some good ideas.
Thanks in advance.
Student: ID, Name, ...
Class: ID, Name, MaxStudents, ...
Student_in_Class: STUDENT_ID, CLASS_ID, DATE_ENROLL
*Not a mySql guru, I typically deal w/ MS SQL, but I think you'll get the idea. You might need to dig a little in the mySql docs to find appropriate data types that match the ones I've suggested. Also, I only gave brief explanation for some types to clarify what they're for, since this is mySql and not MS SQL.
Class_Enrollment - stores the classes each student is registered for
Class_Enrollment_ID INT IDENTITY PK ("identity is made specifically
to serve as an id and it's a field that the system will manage
on its own. It automatically gets updated when a new record is
created. I would try to find something similar in mySql")
Class_ID INT FK
Student_ID INT FK
Date_Time smalldatetime ("smalldatetime just stores the date as a
smaller range of years than datetime + time up to minutes")
put a unique constraint index on class_id and student_id to prevent duplicates
Class - stores your classes
Class_ID INT IDENTITY PK
Name VARCHAR('size') UNIQUE CONSTRAINT INDEX ("UNIQUE CONSTRAINT INDEX is
like a PK, but you can have more than one in a table")
Max_Enrollment INT ("unless you have a different max for different sessions
of the same class, then you only need to define max enrollment once per
class, so it belongs in the class table, not the Class_Enrollment table")
Student - stores your students
Student_ID INT IDENTITY PK
First_Name VARCHAR('size')
Last_Name VARCHAR('size')
Date_of_Birth smalldatetime ("smalldatetime can store just the date,
will automatically put 0's for the time, works fine")
put a unique constraint index on fname, lname, and date of birth to eliminate duplicates (you may have two John Smiths, but two John Smiths w/ exact same birth date in same database is unlikely unless it's a very large database. Otherwise, consider using first name, last name, and phone as a unique constraint)