I'm designing a database in MySQL, and have a couple of questions about how tables and columns ought to be defined.
Right now, I have one entity (let's call it Entity1) that will have several (5-10) features that may change with time. I will also need to be able to add features as time progresses. There are 2 designs I'm considering:
1: 1 table with Entity1 info, 1 table with a timestamp and then all of the features at that given timestamp in every row. This will make it easier to enforce the connections between all of the features.
2: 1 table with Entity1 info, and 1 table for each feature, with each having a timestamp of the addition of that row. This will reduce the amount of redundant data I store in my database.
Are either of these designs ideal? Is there some database literature I should look at? I'm a total noob with database design.
Thanks
Consider creating 2 tables: entity table and feature table.
entity (id, ...)
feature(id, entity_id_foreign_key, feature_name, created_timestamp, feature_value)
It will work if feature values are all equal type. Good thing is that you don't ever need to touch the schema if you want to add or remove features, so no migrations.
Related
This is something that has bothered me for a long time and i still have been unable to find an answer.
I have a huge system with alot of different features. What is common for this system is of course that my users can
create, update, read & delete
different parts of my system.
For simple reasons lets say i have an application that has the following features:
Document administration
Video administration
User administration
Salery administration
(Please do note i took these at random just to prove a point that all of these would have their own separate tables and does not necessarily be connected).
Now i wish to create some sort of logging system. So that when ever someone either create,update or delete an entity it will be recorded.
Now as far as i can see i can do this two ways.
1.
Create a logging table for each of the 4 features that is in my system. However with this method i am required to create a logging table for each new feature i add to the system. i would also have to combine data from X number of tables if i wish to create a log which potentially could be a huge task!
2.
i could create something like the following:
However once again i would have to add a col for each new feature i will add.
So my question is what is the best way for creating logging database architecture
Or is there an easier way?
Instead of one target_xx for each feature, you could do it this way:
target_id | target_type
1 video
4 document
5 user
2 user
or even better. A table with target types and insert only the respective id's on target_type
Something like this:
if you want to capture for each table creation and update date, i would just use the default and the update event from mysql. You can define the fields like this for a table:
ALTER TABLE table
ADD COLUMN CreateDate Datetime DEFAULT CURRENT_TIMESTAMP,
ADD COLUMN LastModifiedDate Datetime ON UPDATE CURRENT_TIMESTAMP;
You can add these 2 fields in all tables. If you want to use one central table for logging (which might be more difficult to manage, because you always need to create joins, maybe also worse performance), then I would work with triggers.
Currently, I have 48 fields.
I'm completely new to access. This is how I decided to connect everything together.
It doesn't seem to be very effective. Could somebody help me understand how to normalize this database?
Should I try to put employee information in one table, job information in another table and then have an equipment lookup table?
The current job, last job, and previous job can all the SAME table. If you sort this table by descending job start date, then then you have current, last and previous. You thus don’t need nor want a separate table for each of these which really amounts to the concept of a “job”. If sorting by date is not enough, then you could add a column called Job Type (current, previous, etc.). Again, we still only using the one table.
The same goes for Equipment. You really don’t care if the limit is 3 last, or 300 last. By building a normalized table, then ONE form can edit all types and you save MASSIVE amounts of coding and building of tables, User interface software, and that of building quires to retrieve + show the last 3 jobs in a form.
The fact that your design with FAR LESS cost of development allows 3 or 300 last jobs is really moot. More important if some manager comes along and now wants you to save the last 4 jobs, you don’t have some massive re-design here. And you can on the fly add new job types. So in place of current, and say previous, you can also have un-completed, or failed jobs. So adding new business rules means again you don’t add a new type of job table, but only a “type” to the one column you already using to define the job as current or previous.
Identify like objects and make one table to store all of them. In your design you have three tables for equipment but each item of equipment has the same fields; they should be one table. Similarly for jobs, each job is pretty much the same; they should be one table. The same for departments.
Figure out one or more column in each table that can uniquely identify the row in the table (that is, if you know the values for those columns it is impossible for there ever to be two rows with those values). These are your primary keys for your tables.
Identify cases in which an item in one table needs to "point to" (refer to) an item in another table. In this case, make sure that the referring table has a set of columns that match the referred-to table.
When you've done that, you'll have the beginnings of a correctly factored relational database design.
I’m new to SQL so please forgive if my terminology is a little out. I’m using phpMyAdmin v3.4 and MySQL (server version) v5.5, I’m building a simple database (only 3 or 4 tables) as a goodwill gesture for my golf club that allows a member to sign-up to play in competitions held on a Saturday or Sunday. The Member may play on both days if they wish (and if they have the energy!) but they may only play once a day. Tables are:
MEMBERS: memberName, memberID
TEE_TIMES: day (choice of Saturday or Sunday), time
BOOKINGS: day_FK, time_FK, memberID_FK, bookingRef
Problem I have with the BOOKINGS table is that I currently have memberID_FK as unique which is fine 95% of the time as most members would play on one day or the other and hence they would only appear in the table once. However, there will be the odd member who will wish to play on “both” days. I could get around this by having 2 BOOKINGS tables (rather than 1), e.g. BOOKINGS_SATURDAY and a separate table for BOOKINGS_SUNDAY, however I believe that would be bad practice and inefficient as I’d have 2 identical table structures (albeit with different names) to manage rather than 1.
I guess what I’m asking is can (memberID_FK) uniqueness be switched on or off depending on another constraint or other variable within a table (in this case the day of choice) - perhaps some kind of clever / dynamic relation between memberID_FK and day_FK? I’d rather implement this as a SQL table structure as I’m not yet familiar with coding although, I’m totally open to a different way of achieving the end goal e.g. splitting the table further (rather than duplicating the structure).
Use a composite unique key:
CREATE TABLE Bookings
...
UNIQUE KEY member_day (memberID_FK, day_FK)
FK are not unique, they usually are on the many side of a one - many relationship.
Make a unique key across member_id and day (maybe even include time ?)
The PK (in your case the memberID from the members table and the day from the tee times table) should be unique, But the FK side is ok not to be unique
Which do you recommend and why?
I have a few tables, when i make a change to the data... it should go to a history table (audit) with a effective date.
The other solution is versioning each field to insert a new row when making changes to the data?
Which is the best method for the invoice information? Item name and price is always change
These are slowly changing dimensions, type 2 and type 4, appropriately.
Both methods are valid and may be more appropriate for your needs, depending on your model and query requirements.
Basically, type 2 (versioning) is more appropriate when you need to query historical values as often as the current one, while type 4 (history table) is more suited when you are querying the current value more often and there are more queries (more queries to develop I mean) against the most recent value.
A system we use and happy with:
Each table that requires history, we create a similar table and adding a timestamp field at the end, which becomes a part of the PK.
Each update on original table, we insert into history table with the same conditions:
update table x WHERE somthing something
insert into table x_history
select * from x WHERE something something
That keeps your data clean and your tables slim.
My personal preference would be to user the Observer Pattern in your application and to implement a separate history table. This means that you can pull the data from the history table when you need it and you don't compromise the speed of querying the main table.
currently Im working on a project that, at first glance, will require many tables in a database. Most of the tables are fairly straightforward however I do have an issue. One of the tables will be a list of members for the website, things like username, password, contact info, bio, education, etc will be included. This is a simple design, however, there is also a need for each member to have their availability entered and store in the database as well. Availability is defined as a date and time range. Like available on 4/5/2011 from 1pm to 6pm EST, or NOT available every friday after 8pm EST. For a single user, this could be a table on its own, but for many users, Im not sure how to go about organizing the data in a manageable fashion. First thought would be to have code to create a table for each user, but that could mean alot of tables in the database in addition to the few I have for other site functions. Logically i could use the username appended to Avail_ or something for the table name ie: Avail_UserBob and then query that as needed. But im curious if anyone can think of a better option than having the potential of hundreds of tables in a single database.
edit
So general agreement would be to have a table for members, unique key being ID for instance. Then have a second table for availability (date, start time, end time, boolean for available or not, and id of member this applies to). Django might sound nice and work well, but i dont have the time to spend learning another framework while working on this project. The 2 table method seems plausable but Im worried about the extra coding required for features that will utilize the availability times to A) build a calender like page to add, edit, or remove entered values, and B) match availabilities with entries from another table that lists games. While I might have more coding, I can live with that as long as the database is sound, functional, and not so messy. Thanks for the input guys.
Not to sound like a troll, but you should take a look into using a web framework to build most of this for you. I'd suggest taking a look at Django. With it you can define the type of fields you wish to store (and how they relate) and Django builds all the SQL statements to make it so. You get a nice admin interface for free so staff can login and add/edit/etc.
You also don't have to worry about building the login/auth/change password, etc. forms. all that session stuff is taken care of by Django. You get to focus on what makes your project/app unique.
And it allow you to build your project really, really fast.
djangoproject.org
I don't have any other framework suggestions that meet your needs. I do... but I think Django will fit the bill.
Create a table to store users. Use its primary key as foreign key in other tables.
The databases are written to hold many many rows in a table. There are not optimized for table creation. So it is not a good idea to create a new table for each user. Instead give each user an unique identifier and put the availability in a separate table. Provide an additional flag to make an entry valid or invalid.
Create a table of users; then create a table of availabilities per user. Don't try to cram availabilities into the user table: that will guarantee giant grief for you later on; and you'll find you have to create an availabilities table then.
Google database normalization to get an idea why.
Take it as truth from one who has suffered such self-inflicted grief :-)