Insert an entire column content into another table plus a value - mysql

Ok, I am new to SQL, so this must sound stupid. Sorry for that.
I have two tables + one junction table (many to many schema) = total of three tables.
First table
students: student_id (PRIMARY) | name | email | password |...
Second table
topics: topic_id (PRIMARY) | topic_name | subject |...
Third table (junction)
jnct_students_topics: id (PRIMARY) | student_id_FK | topic_id_FK | done (boolean) | notes
So how the web app would work?
Second table (topics) is pre-filled with all the topics students need to study.
First table (students) will be filled whenever a new student register for the service.
Junction table (jnct_students_topics) will also be filled when student registers, but (HERE COMES THE QUESTION) I need to know how to insert all topics ids + this student id in topic_id_FK and student_id_FK columns.
Because when a student registers, system will create a list for him/her with all topics to study and a checkbox for each one. After student finishs with topic studying, he/she will check the box and the boolean done column will become true for this topic.
I learned from [this question] (Copy from one column to another (different tables same database) mysql) that, to populate a table column with values from another table column, I could go:
INSERT INTO jnct_students_topics (topic_id_FK)
SELECT topic_id
FROM topics
but I need to build the statement so at the same time the student_id (related to the student that is registering) is inserted (column student_id_FK) in all rows that are being created.
Tired of reading? Well, I don't blame you. Nor english or SQL are native languages of mine... :)
By the way, If you think that this schema is not the best, please, I would appreciate some advice.
Thanks!

Related

How to better build a database

We have a DB on SQL, where we have a table (1) for users and a table (2) for user's saved information. Each piece of information is one line in table (2). So my question is the following - If we are intending to grow number of users to more than 1.000.000 and each user can have more than 10 piece of information, which of the following is a better way to build our DB:
a) Having 2 tables - 1 for users and 1 for information from all users, related to users with ID
b) Having a separate table for each user.
Thanks in advance.
Definitely it should be having a single table for the user is much better. Think from the DB prospective. You are thinking about the search time in a 1.000.000 row for a sorted ID. In the second case you have to search 1.000.000 table to get into a right table. So better go for option A.
I'm going to agree that option A is the better of the two options presented.
That being said, I would personally break up the information for the users into more tables as well. This would all be connected using foreign keys and will allow for more specific querying of the information.
SQL is not really horizontally scalable, so if you end up with users with less or more information than others, then you'll have NULL columns and this requires dealing with in various ways.
By using separate tables, you can still have all of the information contained, but not have to worry if one user has a home and cell phone number, while another only has a cell number.
If and when you do need to access a lot of the information at once, SQL is very good at dealing with this through joins and the like.
Option B is not bad, it just does not fit SQL. I would work if the DB in question was document based instead of tables. In that case, creating a single document for each user is a good idea, and likely preferred.
Option C)
table for users with a unique UserID as Clustered Index (Primary Key)
table for Type of saved information with a unique InformationID as Clustered Index (Primary Key)
table for UserInformation with unique UserInformationID as Clustered Index (Primary Key), a column for UserID (nonclustered index, foreign key to user table) and a column for InformationID (nonclustered index, foreign key to Information table). Have a "Value" or similar column to hold the data being save as it relates to the type of information.
Example:
Users Table
UserID UserName
1 | UserName1
2 | UserName2
Information Table
InfoID InfoName
1 | FavoriteColor
2 | FavoriteNumber
3 | Birthday
UserInformation Table
ID UserID InfoID Value
1 | 1 | 1 | Blue
2 | 1 | 2 | 7
3 | 1 | 3 | '11/01/1999'
4 | 2 | 3 | '05/16/1960'
This method allows for you to save any combination of values for any user without recording any of the non-supplied user information. It keeps the information table 'clean' because you won't need to keep adding columns for each new piece of information you wish to track. Just add a new record to the Info table, and then record only the values submitted to the UserInformation table.

Table item many relationship

I know this is not code realated but wasnt sure where to post it. If this is the wrong spot please let me know where to post as opposed to just a down vote. Basically I am setting up my first DB on my own. I am a little conffused on how to set some tables up. I understand the basic relational model by using a unique ID to pair up tables but what about an item in a table that has many relations.
Examble:
User Table
ID | Name | Email
Product Table
ID | Name | Price | User_ID
Now I know I can pair the 2 using the User_ID in the product table but what if the product can belong to multiple users? How do I associate the the product by using the User_ID to multiple users?

Multiple foreign key for 'extra data' table

i have a logical question for optimization tables relation in MySQL (and even other DBMS).
there are many table with different columns and structures in my database. for a specific reason, i need to create a new table, names "extra_data" with there columns (id, table, content). each table (even "extra_data" itself) MAY needs to store extra data for undefined columns. so this extra data that is a PHP array or object, first serialized and then transform to Base64 code and inserted to "eaxtra_data" table content column. id and table name of target table row, stored in id and table columns in "extra_data" too.
for example if there is two tables names "users" and "posts" and each of them need to store extra data in "extra_data" table:
"users" table:
id name gender ...
1 Tom Male ...
2 Mary Female ...
3 Jack Male ...
...
 
"posts" table:
id title date ...
1 news 4/11/2014 ...
2 article 4/51/2014 ...
...
 
"extra_data" table:
id table content
1 users #$!^...
2 users #$!^...
2 posts #$!^...
...
id and table is primary key in "extra_data" table. so problem is when target row (form example row 2 in users) has been changed or removed, related row in "extra_data" must updated automatically if it's necessary. but the way to set foreign key in many table and in two columns (id, table) together, is imprecise to me! thanx for any help
DarkMaze,
I see where you come from with this "extra_data" table. I don't agree, though. Once it goes against the principles of database normalization and this logic is not clear on a design perspective. I'd rather serialize whatever data you want to add to extra_data content column and save it into its respective table.
Back on the question, the only solution I see so far is to add triggers on every table related to "extra_data" in order to add/remove/update records. Which is not very productive.
Cheers,
http://en.wikipedia.org/wiki/Database_normalization

How to map two tables in database PHPMyAdmin

I'm working on a project in which a user can save their own coupon codes on the website, so I want to know what is the best way to do that.
Lets say, I have 1 table with the users, like this:
userId | firstName | lastName | codeId
And then I have a table of the coupon codes, like this:
codeId | codeNumber
So what I can do is to connect the codeId to userId so when someone saves the coupons the codeId from the coupon table goes into the codeId of the users table.
But now what do I do if when user has multiple coupons? How should they be connected to the user?
I have 2 options what to do:
Saving the codeId from coupons table into the codeId of users table like 1,2,3,4,5,
Make a new row into the coupons table and connect the user to the code by adding another field in the coupon table userId and putting into it the userId of the user which has added the coupon.
So which of the two options is better?
A many-to-many relationship between two tables should be solved by adding a third table connecting the two:
user_coupons
- userId
- couponId
Your first option violates the 1-NF rule, where it says that no column will have a group of values.
This is a typical one-to-many relationship. Your second option of creating a separate table User_Coupons (not the the underscore) and create a row with UserID, CouponCode, for each association. The two columns together should be unique so that they both become the primary key of the associative table.
If i was you my database will be:
userId | firstName | lastName
codeNumber | userId
You can insert many codeNumber for any user if you want.

Database table design - are my fields correct?

I need to sell items on my fictitious website and as such have come up with a couple of tables and was wondering if anyone could let me know if this is plausible and if not where i might be able to change things?
I am thinking along the lines of;
Products table : ID, Name, Cost, mediaType(FK)
Media: Id, Name(book, cd, dvd etc)
What is confusing me is that a user might have / own many products, but how would you store an array of product id's in a single column?
Thanks
You could something like store a JSON array in a text or varchar field and let the application handle parsing it.
MySQL doesn't have a native array type, unlike say PostgreSQL, but in general I find if you're trying to store an array you're probably doing something wrong. Of course every rule has its exceptions.
What your probably want is a user table and then a table that correlates products to users. If a product is only going to relate to one user then you can add a user ID column to your Products table. If not, then you'll want another lookup table which handles the many to many relationship. It would look something like this:
------------------------
| user_id | product_id |
------------------------
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 2 |
| 3 | 1 |
| 3 | 5 |
------------------------
I think one way of storing all the products which user has in one column is to store it as a string where product ids are separated by some delimiters like comma. Though this is not the way you want to solve. The best way to solve this problem would be to have a seperate user table and than have a user product table where you associate userid with product id. You could than simple use a simple query to get list of all the products owned by a particular userid
As a starting point, try to think of the system in terms of the major parts - you would have a 'warehouse', so you need a table to list the products you have, and you are going to possibly have users who register their details with you for regular visits - so an account per user. You would generally hold all details of a single product in the same row of the same table (unless you have a really complex product to detail, but not likely). If you're going to keep track of products bought per user account, there's always the option of keeping the order history as a delimited list in a large text field. For example: date,id,id,id,id;date,id,id. Or you could simply refer to order numbers and have a separate table for orders placed [by any customer].
What is confusing me is that a user might have / own many products, but how would you store an array of product id's in a single column?
This is called a "many-to-many" relationship. In essence you would have a table for users, a table for products, and a table to map them like this:
[table] Users
- id
- name
[table] Products
- id
- name
- price
[table] Users_Products
- user_id
- product_id
Then when you want to know what products a user has, you could perform a query like:
SELECT product_id FROM Users_Products WHERE user_id=23;
Of course, user id 23 is fictituous for examples sake. The resulting recordset would contain the id's of all the products the user owns.
You wouldn't store an array of things into a single column. In fact you usually wouldn't store them in separate columns either.
You need to step away from design for a bit and go investigate third normal form. That should be you starting point and, in the vast majority of cases, your ending point for designing database schemas.
The correct way of handling variable size "arrays" is with two tables with a many to one relationship, something like:
Users
User ID (primary key)
Name
Other user info
Objects:
Object Id (primary key)
User id (foreign key, references Users(User id)
Other object info
That's the simplest form where one object is tied to a specific user, but a specific user may have any number of objects.
Where an object can be "owned" by multiple users (I say an object meaning (for example) the book "Death of a Salesman", but obviously each user has their own copy of an object), you use a joining table:
Users
User ID (primary key)
Name
Other user info
Objects:
Object Id (primary key)
User id (foreign key, references Users(User id))
Other object info
UserObjects:
User id (foreign key, references Users(User id))
Object id (foreign key, references Objects(Object id))
Count
primary key (User id, Object id)
Similarly, you can handle one or more by adding an object id to the Users table.
But, until you've nutted out the simplest form and understand 3NF, they won't generally matter to you.