I have looked around and found some questions similar but they were for SQL Server instead.
Here is a small database structured I have create just to show you the relationships I want to model. Basically it's quite simple, each year has 12 periods and an instance of period-year cannot occur twice (period 9 year 2012 cannot occur more than once ever).
So I thought that the best way to model this would be to have a table period with only one field with values from 1-12, a table year following the same logic (2011,2012...) and since it is an N-to-N relationship I have created the period_by_year table which joins them to be used by rpt_maintenance_kpi. Now the tricky part is that in order to make each combination unique, I have made the both period_no and year_no part of a composite primary key. This solves the problem elegantly in my opinion, but then I am stuck on how to reference this composite primary key from the rpt_maintenance_kpi (or any other table for that matter). I have tried making two joins but this does not seem to work (creates a second rpt_maintenance_kpi table and I believe this will not do what I want to do).
So how could I handle a foreign key to a composite primary key ?
Many thanks in advance.
Create the Year or Period relationship with Maintenance, then either double-click the relationship line to edit the relationship or drag the second part (year or period accordingly) to Maintenance and choose Yes when asked if you want to edit the relationship. You can now add the second line, like so:
Composite keys are of course helpful and solve your problems, but if you really want to avoid composite key joins, another alternate way of accomplishing what you require is to slightly re-design your table structure. As end reports are always sought based on month & year combination, it would help to have a MthYear dimension (or table). The following can be the entries in that table - with a yymm format:
1301
1302
1303
...
...
...
1312
1401
1402
...
...
etc....
You can have further attributes in the same table in more descriptive form like second field could be Jan-13, Feb-13....etc.
The MthYear field can be your primary field which can be connected to MthYear in your report maint table. This will not only avoid using composite primary keys but also help you to filter only year or month if you require using wildcard characters in your queries or reports. Hope this is helpful to you......Arvind
Related
I started to design a database that tracks system events by following some online tutorials, and some easy examples start by assigning auto-incrementing IDs as primary keys. I looked at my database, I don't really need IDs. Out of all my columns, the timestamp and device ID are the two columns that together identifies an unique event.
What my program does right now is to pull some events from system log in the past x minutes and insert these events to the database. However, I could be going too much into the past that the events overlap with what's already in the database. As I mentioned before, timestamp and device ID are the two fields that uniquely identify an event. My question is, should I use these two fields as my primary key and use "Insert ignore" from now on so I can avoid having duplicate records?
It is a good practise to never have your business values as table's primary key and always to use synthetic, e.g. autoincrement, values for this. You will make your life easier in the future when business requirements change :)
We are currently struggling with exactly this situation. Have a column with business values as a primary key for 2 years and now painfully introducing an autoincrement one.
You may need to use foreign key from other table to this in the future to link some rows between two tables. It is easier with one-column primary key.
But if you don't need it now - no need to create column special for index. Table can be altered in future to add such column with autoincrement and move primary key to it.
We are currently in the process of developing our own e-commerce solution, as part of our research we have been examining the ZenCart Database Schema and found that data is quite frequently duplicated between various tables where it would seem that perhaps a Foreign Key would have been sufficient to link the two or more tables in question, for example:
Given that there is table "Products" that has the following columns
PRODUCT_IDPRODUCT_NAMEPRODUCT_PRICEPRODUCT_SKU
Then if there is a Sales_Item "Table" Then of course a product (and all its constituent columns)may be referenced by simply doing something like:
SALES_ITEM_IDProducts_PRODUCT_ID //This is the foreign key that relates a specific product to a sale item.SALE_TIMEREST_OF_SALE_SPECIFIC_DATA......
However instead it seems that the Sales table COPIES many of the field values defined in the Products table so it infact looks as follows:
SALES_ITEM_IDPRODUCT_IDPRODUCT_NAMEPRODUCT_PRICEPRODUCT_SKUSALE_TIME
My question is which approach would generally be considered best practice when attempting to build a scalable efficient solution. Using foreign keys means data is not duplicated but the caveat is that database or application-level JOINS would be needed in order to query the entire dataset. However than being said, for some reason the foreign key approach seems cleaner and more correct somehow.
Can someone help me understand this as I'm not sure if I should include a primary key in this one, because it doesn't look like I need it.
I have two table structures as follow:
Table 1: programs
program_id
cycle_unit
Table 2: program_has_days
day
week
program_id
A program can take many days to complete, so the program has a schedule which is in table 2. The schedule list the day in the week (example day 1 of week 1, then day 3 of week 2) that the program can be completed. So here, it has a one to many relationship. I'm wondering should I put an primary key (id) to table number 2?
I don't think I'll need the primary key, as I won't be referring to the schedule directly. I always refer to the program_id to get the schedule. In this case, program_id can't be the primary key because it is not unique.
Yes, good practice; No, not required. It's good practice for every table to have a primary key. This will help you later if you decide you do actually need to reference the table's data - even if it's just to delete a few rows without having to specify some other unique set of its fields.
If you're not going to have many programs running over the same days/weeks, there's no need for a PK on table 2.
But if you're going to have many programs running on the same days/weeks then you may wish to add a PK on Table 2, and have a third joining table between them. This way, you won't end up with multiple rows in Table 2 for the same day/week combination (ie no point keeping a row for every program that exists on that particular day/week). Although this would add complexity in checking if an appropriate day/week already exists.
This approach would be particularly relevant if you're interested in efficiently searching on which programs run on a particular day/week (but you've said you're not...).
Another case might be if you need a program to run on multiple schedules (eg the program will run for a few weeks (with different records for each day as you've outline), but then again the program will be re-run in 6 months on a different schedule day/week, etc. Or perhaps 2 different, but concurrent schedules?) . This would require a PK on table 2 with a joining table to keep track of the separate schedules OR another key on table 2 to distinguish which instance of a schedule a particular day/week/program combination a record belongs to.
I am trying to create a simple Registration Program using VB.Net and MySQL for its database. Here's my simple table for the basic Information
However, I am attempting to improve my basic knowledge in normalization of table and that's why I separated the Date field to avoid, let say in one day, the repeated insertion of the same date. I mean, when 50 individuals registered in one day, it will simply add a single date(record) in tblRegDate table instead of adding it up for 50 times in a table. Is there any way to do this? Is it possible in VB.Net and MySQL? Or rather, should I add or modify some field? or should I make a condition in VB.Net? The table above is what my friend taught me but I discovered that it doesn't eliminate the redundancy. Kindly give me any instruction or direct me to site where there's a simple tutorial for this. Thanks in advance!
here's my MySQL codes:
CREATE TABLE tblInfo(
Number INT AUTO_INCREMENT,
LastName VARCHAR(45),
FirstName VARCHAR(45),
MiddleName VARCHAR(45),
Gender ENUM(M,F),
BirthDate DATE,
PRIMARY KEY(Number));
CREATE TABLE tblRegDate(
IDRegDate INT AUTO_INCREMENT,
Date TIMESTAMP,
Number INT,
PRIMARY KEY(IDRegDate),
FOREIGN KEY(Number) REFERENCES tblInfo(Number));
As I see it in this case you don't have advanages of seperating a single field. You'll loose a lot of performance.
Table normalization isn't about don't having any redundant value. It's more about "Seperating the concerns"
Also it is important to not have an exploding complexity in your database. seperating single fills would end up in a database no one would be able to understand.
The Question is: Are there more informations on registration ? For Example Webpage, IP, .....
Than you should have two tables for example "Person" and "Registration". Then you would have two semantic different things which shouldn't be mixed up.
There are a lot of examples and information you can find via google. and wikipedia
http://en.wikipedia.org/wiki/Database_normalization
Actually it is not a good idea to seperate timestamp from the table.
You would need another table namely i.e timeTable. It would have two columns id and timestmap and you should reference this id in your tblRegDate table as foreign key.
Foreign key is an integer and has the size 4 bytes. Date on the other hand 3 bytes.
Therefore I would recommend you to keep date in your tblRegDate and not in a extra table
When you normalize DB structures, always keep it mind of ACID - http://en.wikipedia.org/wiki/ACID
Based on the fields you have, you should just keep it as a single table. Separating out the registration date is not a good design because you'll have to do a look up every time. In real life, you can consider indexing the reg date if your app always search or sort by regdate.
And if you FK RegDate table to the user table, it is also not efficient.
p.s. Also keep in mind that there are 4 levels of DB normalization. If you are new to DB design, you should consider learning how to move a DB design from 1st to 2nd, and 2nd to 3rd normal forms.
We rarely use 4th normal form in real life situation. Transaction systems usually stay at 3rd most of the time.
Hope that make sense.
I am attempting to build a database for inventory control using a large number of tables and enforced relationships, and I just ran into the 32-relationship (index) limit for an Access table (using Access 2007).
Just to clarify: the problem isn't that the Employees table has 32 explicit indexes. Rather, the problem is the limitation on the number of times the Employee table can be referenced in FOREIGN KEY constraints. For example:
CREATE TABLE Employees (employee_number INTEGER NOT NULL UNIQUE)
;
CREATE TABLE Table01 (employee_number INTEGER NOT NULL REFERENCES Employees (employee_number))
;
CREATE TABLE Table02 (employee_number INTEGER NOT NULL REFERENCES Employees (employee_number))
;
CREATE TABLE Table03 (employee_number INTEGER NOT NULL REFERENCES Employees (employee_number))
;
...
CREATE TABLE Table30 (employee_number INTEGER NOT NULL REFERENCES Employees (employee_number))
;
CREATE TABLE Table31 (employee_number INTEGER NOT NULL REFERENCES Employees (employee_number))
;
CREATE TABLE Table32 (employee_number INTEGER NOT NULL REFERENCES Employees (employee_number))
;
An exception is thrown on the last line above, "Could not create index; too many indexes defined.
What options do I have to work around this limitation?
I've heard that creating a duplicate table with a 1:1 relationship is one method. I'm new to database design, so please correct me if I'm wrong; but given a table Employees with 31 indexes, I would create a table Employees2(with one field?) with a 1:1 relationship to Employees and relationships to this new table from any remaining relations in which EmployeeID is a foreign key. What's the best way to ensure the second table is populated alongside the first?
Is there another approach?
Based on the lack of information available, it seems this may be a rare problem with a properly-designed database, or the solution is common knowledge. Forgive the noob!
Update: Immediate consensus is that my design is borked or far too ambitious. This could very well be the case. However, I'd rather have a general design discussion within a separate question, so for the sake of argument, can someone answer this one? If the answer is simply "Don't ever do that" I'll have to accept it.
I've run into this limitation a number of times with my apps. And I can assure the other posters that my apps are very well designed.
One problem is that Access creates indexes due to relationships and lookup fields that aren't viewable on the main index property box but they are accessible via DAO collections. These indexes are frequently duplicate indexes to indexes you have created as well.
I have a tool consisting of several forms you import into your BE MDB that allows you to remove the duplicate indexes. As I haven't yet made this available on my website please email me for it.
I'd suggest just not defining all the relationships/indexes to implementing a 1:1 relationship to get around it. Neither solution is optimal, but the later is going to create a much higher maintenance burden and data anomaly potential.
I am not going to decry the design as quicky as some of the others, but it does have me intrigued. Could you list the fields of the employee table that are foreign keys? There is a good liklihood that some normalization is in order and maybe some of the smart people on SO could make some design suggestions to work around the issue.
It is hard for me to believe that an Employee table would need 32 indexes; if it actually does you should consider migrating to at least SQL Express.
... I would create a table
Employees2(with one field?) with a 1:1
relationship to Employees and
relationships to this new table from
any remaining relations in which
EmployeeID is a foreign key.
That is workable. Presumably your main table might have an Autonumber field as the primary key, or you generate an index number. Your Employees2 table obviously must echo that.
What's the best way to ensure the
second table is populated alongside
the first?
That depends somewhat on how you are adding records. But in general, of course you must comply with the rules for integrity. This usually comes down to appending to tables in the correct order and ensuring each record is saved before trying to add a related record elsewhere.