I'm having a hard time representing the following situation in the database:
A user can declare multiple addresses (such as Home, Office, Mailing etc. as requested by client).
I have an auto-incremented primary key called UserID that represents one user account. I've been thinking of making a BelongsToUserID column to represent each user's form field to look like:
I can't do this because each row can only be occupied by UserID row.
Any thoughts on how to achieve this?
You want a separate table holding the addresses. Perhaps something like:
| id(primary key) | type(enum home/work/etc.) | userID | address |
you can make this in two ways
first one is simple but not adviced is that you don't make any primary key and use composite key pair as the candidate key and choose primary from that. as the table is missing the primary key its not adviced
second approach is good and i also use that is to make a master table and use that as the relation-table there and use another table to actually store the data.
in master table you can have id, userid, address_bit, and in second table you can have id, address_bit, address.
please tell me any other solution if you found one. It might help me to learn new :)
Related
I am in a situation where i have to store key -> value pairs in a table which signifies users who have voted certain products.
UserId ProductID
1 2345
1 1786
6 657
2 1254
1 2187
As you can see that userId keeps on repeating and so can productId. I wanted to know what can be the best way to represent this data. Also is there a necessity of using primary key in here. I've searched a lot but am not able to find the exact specification about my problem. Any help would be appreciated. Thank you.
If you want to enforce that a given user can vote for a given product at most once, create a unique constraint over both columns:
ALTER TABLE mytable ADD UNIQUE INDEX (UserId, ProductID);
Although you can use these two columns together as a key, your app code is often simpler if you define a separate, typically auto increment, key column, but the decision to do this depends on which app code language/library you use.
If you have any tables that hold a foreign key reference to this table, and you intend to use referential integrity, those tables and the SQL used to define the relationship will also be simpler if you create a separate key column - you just end up carting multiple columns around instead of just one.
Let's assume there is a table, with theese rows:
-personID,
-personName,
-personInterests
There is also another table, which stores the interests:
-interestID
-interestName
One person can have multiple interests, so I put the serialize()-d or JSON representation of the interest array into the interest field. This is not a String, like "reading", buth rather an index of the interests table, which stores the possible interests. Something like multiple foreign keys in one field.
The best way would be to use foreign keys, but it is not possible to achieve multiple references in one field...
How do I run such a query, without REGEX or splitting the field's content by software? If putting indexes to one field is not the way to go, then how is it possible, to achieve a structure like this?
Storing multiple indexes or any references in one field is strictly not advised.
You have to create something that I call "rendezvous" table.
In your case it has:
- ID
- UserID (foreign key)
- InterestID (foreign key)
Every single person can have multiple interests, so when a person adds a new interest to himself, you just add a new row into this table, that will have a reference to the person and the desired interest with a foreign key NOT NULL.
On large-scale projects when there are too many variations available, it is advised, to not to give an ID row to this table, but rather set the two foreign keys also primary keys, so the duplication will be impossible and the table-index will be smaller, as well as in case of lookup, it will consume less from the expensive computing power.
So the best solution is this:
- UserID (foreign key AND primary key)
- InterestID (foreign key AND primary key)
I believe the only way you can implement this is to create a third table, which will actually get updated by a trigger (Similar to what Gabor Dani advised)
Table1
-personID,
-personName,
-personInterests
Table2
-interestID
-interestName
Table3
-personInterestID (AutoIncrement Field)
-personID
-interestID
Then you need to write a trigger which will do this a stored procedure may be needed because you will need to loop through all the values in the field.
There are four regions with more than one million records total. Should I create a table with a region column or a table for each region and combine them to get the top ranks?
If I combine all four regions, none of my columns will be unique so I will need to also add an id column for my primary key. Otherwise, name, accountId & characterId would be candidate keys or should I just add an id column anyways.
Table:
----------------------------------------------------------------
| name | accountId | iconId | level | characterId | updateDate |
----------------------------------------------------------------
Edit:
Should I look into partitioning the table by region_id?
Because all records are related to a particular region, a single database table in 3NF(e.g All-Regions) containing a regionId along with other attributes should work.
The correct answer, as usually with database design, is "It depends".
First of all, (IMHO) a good primary key should belong to the database, not to the users :)
So, if accountId and characterId are user-editable or prominently displayed to the user, they should not be used for the primary key of the table(s) anyway. And using name (or any other user-generated string) for a key is just asking for trouble.
As for the regions, try to divine how the records will be used.
Whether most of the queries will use only a single region, or most of them will use data across regions?
Is there a possibility that the schemas for different regions might diverge?
Will there be different usage scenarios for similar data? (e.g. different phone number patterns for different regions)
Bottom line, both approaches will work, let your data tell you which approach will be more manageable.
I've seen a lot of discussion regarding this. I'm just seeking for your suggestions regarding this. Basically, what I'm using is PHP and MySQL. I have a users table which goes:
users
------------------------------
uid(pk) | username | password
------------------------------
12 | user1 | hashedpw
------------------------------
and another table which stores updates by the user
updates
--------------------------------------------
uid | date | content
--------------------------------------------
12 | 2011-11-17 08:21:01 | updated profile
12 | 2011-11-17 11:42:01 | created group
--------------------------------------------
The user's profile page will show the 5 most recent updates of a user. The questions are:
For the updates table, would it be possible to set both uid and date as composite primary keys with uid referencing uid from users
OR would it be better to just create another column in updates which auto-increments and will be used as the primary key (while uid will be FK to uid in users)?
Your idea (under 1.) rests on the assumption that a user can never do two "updates" within one second. That is very poor design. You never know what functions you will implement in the future, but chances are that some day 1 click leads to 2 actions and therefore 2 lines in this table.
I say "updates" quoted because I see this more as a logging table. And who knows what you may want to log somewhere in the future.
As for unusual primary keys: don't do it, it almost always comes right back in your face and you have to do a lot of work to add a proper autoincremented key afterwards.
It depends on the requirement but a third possibility is that you could make the key (uid, date, content). You could still add a surrogate key as well but in that case you would presumably want to implement both keys - a composite and a surrogate - not just one. Don't make the mistake of thinking you have to make an either/or choice.
Whether it is useful to add the surrogate or not depends on how it's being used - don't add a surrogate unless or until you need it. In any case uid I would assume to be a foreign key referencing the users table.
In MySQL, I was advised to store the multiple choice options for "Drugs" as a separate table user_drug where each row is one of the options selected by a particular user. I was also advised to create a 3rd table drug that describes each option selected in table user_drug. Here is an example:
user
id name income
1 Foo 10000
2 Bar 20000
3 Baz 30000
drug
id name
1 Marijuana
2 Cocaine
3 Heroin
user_drug
user_id drug_id
1 1
1 2
2 1
2 3
3 3
As you can see, table user_drug can contain the multiple drugs selected by a particular user, and table drug tells you what drug each drug_id is referring to.
I was told a Foreign Key should tie tables user_drug and drug together, but I've never dealt with Foreign Key's so I'm not sure how to do that.
Wouldn't it be easier to get rid of the drug table and simply store the TEXT value of each drug in user_drug? Why or why not?
If adding the 3rd table drug is better, then how would I implement the Foreign Key structure, and how would I normally retrieve the respective values using those Foreign Keys?
(I find it far easier to use just 2 tables, but I've heard Foreign Keys are helpful in that they ensure a proper value is entered, and that it is also a lot faster to search and sort for a drug_id than a text value, so I want to be sure.)
Wouldn't it be easier to get rid of the drug table and simply store the TEXT value of each drug in user_drug? Why or why not?
Easier, yes.
But not better.
Your data would not be normalized, wasting lots of space to store the table.
The index on that field would occupy way more space again wasting space and slowing things down.
If you want to query a drop-down list of possible values, that's trivial with a separate table, hard (read: slow) with just text in a field.
If you just drop text fields in 1 table, it's hard to ensure misspellings do not get in there, with a separate link table preventing misspellings is easy.
If adding the 3rd table drug is better, then how would I implement the Foreign Key structure
ALTER TABLE user_drug ADD FOREIGN KEY fk_drug(drug_id) REFERENCES drug(id);
and how would I normally retrieve the respective values using those Foreign Keys?
SELECT u.name, d.name as drug
FROM user u
INNER JOIN user_drug ud ON (ud.user_id = u.id)
INNER JOIN drug d ON (d.id = ud.drug_id)
Don't forget to declare the primary key for table user_drug as
PRIMARY KEY (user_id, drug_id)
Alternatively
You can use an enum
CREATE TABLE example (
id UNSIGNED INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
example ENUM('value1','value2','value3'),
other_fields .....
You don't get all the benefits of a separate table, but if you just want a few values (e.g. yes/no or male/female/unknown) and you want to make sure it's limited to only those values it's a good compromise.
And much more self documenting and robust than magic constants (1=male, 2=female, 3= unknown,... but what happens if we insert 4?)
Wouldn't it be easier to get rid of the drug table and simply store
the TEXT value of each drug in user_drug? Why or why not?
Normally, you'd have lots of other columns on the drug table -- things like description, medical information, chemical properties, etc. In that case, you wouldn't want to duplicate all of that information on every record of the user_drug table. In this particular case however, you've only got one column, so that issue is not really a big deal.
Also, you want to be sure that the drug referenced in the user_drug table actually exists. For example, if you store the field as text, then you could have heroin and its related misspellings like haroin or herion. This will give you problems when you try to select all heroin records later. Using a foreign key to a lookup table forces the id to exist in that table, so you can be absolutely sure that all references to heroin are accurate.