Mysql database design - mysql

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 :-)

Related

Creating the right Database table structure for address change + pricing

I'm a little stumped on whether i can make this process of changing addresses easier. I'll explain the situation:
Basically I have three entities, Students, Addresses, StudentsAddresses. Students have many addresses, since they can change alot and rapidly (especially foster kids / homeless kids). So ill be changing them a lot. However based on each address I Want a user to attach (enter it via the UI) the price it would cost to pick that student up via bus service. So my initial thought was, ok, let me attach a column onto my join table 'StudentsAddresses' called 'dailyPrice', this is the cost for each day a student is picked up, and another column called 'adjustmentPrice', which is an additional cost for whatever special circumstance that requires extra work to pick up a student. Is my thinking going to cause me problems the more students I have in the future? Will it get harder to manage?
Another option I thought about, was creating a new Table called Pricing. And another join-type table called StudentsAddressesPricing
StudentsAddressPricing has three columns,
studentId
addressId
pricingId
each field connects the three together. So if i ever needed Students, with their addresses, and the pricing, i would query this table and eager load Students, Addresses, and Pricing. Does this approach seem much cleaner since i've abstracted pricing out a bit? Trying to determine the best way to go about this without having to many headaches in the future incase I wan't to add more attributes pricing related, or address related.
And then I even thought, hey what if pricing is just different for one day? How would I even consider that. Would I need a different kind of entity to handle that? Is doing alot of joins going to hurt my application performance?
Just looking for some insight on how others would do it, and criticism on why im off the ball.
The main question you should ask yourself is: on what does the price depend?
If the price is determined by the address, you might as well add it to addresses. If the price also depends on the student (e.g., depending on their financial situation), it would make sense to put it into studentsaddresses.
In other words: The table where the price is stored should have foreign keys to everything outside the table that determines the price. If that makes it fit into one of the existing tables, keep it there.

How to enable users only to view certain rows in a table

I currently have two tables. One is accounts and one is tbl_units_info. My boss wants me to make it so that accounts are restricted from reading certain rows in a table. Frankly, I think my boss has no idea what he is talking about, but I'm hoping someone here can prove me wrong.
For example, accountname krikara can only view the entries of the tbl_units_info table where the TBID column is 0909.
Is this even possible? To make krikara only able to view the rows in that table where column TBID = 0909?
It can not be implemented plainly on DBMS level since SELECT privilege has table level. You can not restrict rows reading. And this is good, I think - because data could be changed, so in general there is no solid condition for rows restriction (and, therefore, there could not be valid implementation for that on DBMS level).
You can, however, use VIEW - but it is a middlepoint, not common solution (I still not think it will help with tracking rows changes, but may be I'm wrong due to your application logic)
You can try to implement it in your application, but it still has problem I've described above: in table, data is changing. You'll probably have troubles with tracking all changes. I think you can separate your rows on two (several) tables and then build your permissions model. But - if some basically similar entities must have different permissions - probably you should reconsider application security model?
You could solve it by giving accounts just the reading rights to a view instead of the whole table.
CREATE VIEW `tbl_units_info_krikara` AS
SELECT * FROM `tbl_units_ino` WHERE `TBID`='0909';
And then assign the respective rights to your user.
MySQL CREATE VIEW documentation

alternative solution to asking user to create a new table

I use access to store concert registration information at the non-profit I currently work at. I have it set up so that I dump all of the patron contact information into one table, and all of the concert registration information into another. when we change our concert season, I simply copy/paste the "2012-13 concert registration table" and rename it the "2013-14" concert registration table".
the concert registration table serves as my "hub" for all my other information. I have about a half-dozen summary queries that show information for specific concerts, who I still need to collect payment for etc. as well as many Word mail merges associated with each document. This setup works great, except that every season I need to go in and re-link all of the queries and word docs to the new registration table
I will be leaving my job at the end of next month, and I would like to make the database more user-friendly, especially since I am fairly certain that my replacement will have zero familiarity with access. my questions are:
1) Is there a more elegant, easy way to transition from season to season other than to create a new registration table and subsequent queries from year-to-year?
2) How can I idiot-proof this database for the new person when I'm gone? I'm scared that if I create an extensive "how-to" guide, it simply won't be read and the person will be forced to reinvent the wheel. I'm toying with creating a switchboard, but I'm scared that this will make the database seem more unapproachable.
Thank you for your insight, happy to clarify if there are any questions!
Just make 1 table. Call it "registration table" and add a new field called Season. Your queries will be include a filter for that field. Then you won't need to relink your queries, copy tables, etc.
For an example, say you have a query to pull all the information from that table for a particular season. It might look something like:
Select * from RegistrationTable where Season=[What Season];
When run, the query will prompt the user for the season and pull only that data.
Also, I do recommend the "how-to" guide. There's probably a lot of manual manipulation of the database that you do and don't even think about. And if nothing else, you can always say you gave them documentation and thus provided for your successor.

Database user table design, for specific scenario

I know this question has been asked and answered many times, and I've spent a decent amount of time reading through the following questions:
Database table structure for user settings
How to handle a few dozen flags in a database
Storing flags in a DB
How many database table columns are too many?
How many columns is too many columns?
The problem is that there seem to be a somewhat even distribution of supporters for a few classes of solutions:
Stick user settings in a single table as long as it's normalized
Split it into two tables that are 1 to 1, for example "users" and "user_settings"
Generalize it with some sort of key-value system
Stick setting flags in bitfield or other serialized form
So at the risk of asking a duplicate question, I'd like to describe my specific scenario, and hopefully get a more specific answer.
Currently my site has a single user table in mysql, with around 10-15 columns(id, name, email, password...)
I'd like to add a set of per-user settings for whether to send email alerts for different types of events (notify_if_user_follows_me, notify_if_user_messages_me, notify_when_friend_posts_new_stuff...)
I anticipate that in the future I'd be infrequently adding one off per-user settings which are mostly 1 to 1 with users.
I'm leaning towards creating a second user_settings table and stick "non-essential" information such as email notification settings there, for the sake of keeping the main user table more readable, but is very curious to hear what expects have to say.
Seems that your dilemma is to vertically partition the user table or not. You may want to read this SO Q/A too.
i'm gonna cast my vote for adding two tables... (some sota key-value system)
it is preferable (to me) to add data instead of columns... so,
add a new table that links users to settings, then add a table for the settings...
these things: notify_if_user_follows_me, notify_if_user_messages_me, notify_when_friend_posts_new_stuff. would then become row insertions with an id, and you can reference them at any time and extend them as needed without changing the schema.

MySQL database model for signups with and without addresses

I've been thinking about this all evening (GMT) but I can't seem to figure out a good solution for this one. Here's the case...
I have to create a signup system which distinguishes 4 kinds of "users":
Individual sign ups (require address info)
Group sign ups (don't require address info)
Group contact (require address info)
Application users (don't require address info)
I really cannot come up with a decent way of modeling this into something that makes sense. I'd greatly appreciate it if you could share your ideas.
Thanks in advance!
Sounds like good case for single table inheritance
Requiring certain data is more a function of your application logic than your database. You can definitely define database columns that don't allow NULL values, but they can be set to "" (empty string) without any errors.
As far as how to structure your database, have two separate tables:
User
UserAddress
When you have a new signup that requires contact info, your application will create records in both tables. When a new signup doesn't require address info, your application will only create a record in the User table.
There are a couple considerations here: first, I like to look at User/Group as a case of a Composite pattern. It clearly meets the requirement: you often have to treat the aggregate and individual versions of the entity interchangeably (as you note). Implementing a composite in a database is not that hard. If you are using an ORM, it is pretty simple (inheritance).
On the other part of the question, you always have the ability to create data structures that are mostly empty. Generally, that's a bad idea. So you can say 'well, in the beginning, we don't have any information about the User so we will just leave all the other fields blank.' A better approach is to try and model the phases as if they were part of an FSM. One of the clearest ways to do this in this particular case is to distinguish between Users, Accounts and some other more domain-specific entity, e.g. Subscriber or Customer. Then, I can come and browse using User, sign up and make an Account, then later when you want address and other personal information, become a subscriber. This would also imply inheritance, and you have the added benefit of being able to have a true representation of the population at any time that doesn't require stupid shenanigans like 'SELECT COUNT(*) WHERE _ not null,' etc.
Here's a suggestion from my end after weighing pro's and con's on this model. As I think the ideal setup is to have all users be a user entity that belong to a group without differentiating groups from individuals (except of course flag a group contact person and creating a link with a groups table) we came up with the alternative to copy the group contact user details to the group members when they group is created.
This way all entities that actually are a person will get their own table.
Could this be a good idea? Awaiting your comments :)
I've decided to go with a construction where group members are separated from the user pool anyway. The group members eventually have no relation with a user since they don't require access to mutating their personal data, that's what a group contact person is for. Eventually I could add a possibility for groups to have multiple contact persons, even distinguishing persons that are or are not allowed to edit any member data.
That's my answer on this one.