I need to store multiple id's in either a field in the table or add another table to store the id's in.
Each member will basically have favourite articles. Each article has an id which is stored when the user clicks on a Add to favourites button.
My question is:
Do I create a field and in this field add the multiple id's or do I create a table to add those id's?
What is the best way to do this?
This is a many-to-many relationship, you need an additional table storing pairs of user_id and article_id (primary keys of user and article tables, respectively).
You should create a new table instead of having comma seperated values in a single column.
Keep your database normalized.
You create a separate table, this is how things work in a relational database. The other solution (comma separated list of ids in one column) will lead to an unmaintainable database. For example, what if you want to know how many times an article was favorited? You cannot write queries on a column like this.
Your table will need to store the user's id and the article's id - these refer to the primary keys of the corresponding tables. For querying, you can either use JOINs or nested SELECT queries.
As lafor already pointed out this is a many-to-many relationship and you'll end up with three tables: user, article, and favorite:
CREATE TABLE user(
id INT NOT NULL,
...
PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE article (
id INT NOT NULL,
...
PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE favorite (
userID INT NOT NULL,
articleID INT NOT NULL,
FOREIGN KEY (userID) REFERENCES user(id) ON DELETE CASCADE,
FOREIGN KEY (articleID) REFERENCES article(id) ON DELETE CASCADE,
PRIMARY KEY (userID, articleID)
) ENGINE=INNODB;
If you then want to select all user's favorite articles you use a JOIN:
SELECT * FROM favorite f JOIN article a ON f.articleID = a.id WHERE f.userID = ?
If you want to know why you should use this schema, I recommend reading about database normilization. With multiple IDs in a single field you would even violate the first normal form and thus land in a world of pain...
Related
Currently, I'm working for my assignment project called 'Competition Management' and I don't know much about SQL and PHP. Afaik, my questions should be workout in PHP to do this or that but I'm just curious with these SQL. You can ignore the empty varchar.
2 Questions
Player Table is related to Competition and Association Table. Do I have to do something with it or just let it be?
In Competition Table, you can see config_competition field... but, the field should contain data inside it... in term of sport competition, lets say we have football sport, gaming e-sport, athlete sport, and etc... In this case, should I create a new table? If yes, how do I make it related with the Competition Table?
This is Organisation Table (who creates a competition)
CREATE TABLE organisation (
id_organisation varchar() PRIMARY KEY,
name_organisation varchar(),
password varchar()
);
This is Competition Table (Created by Organiser)
CREATE TABLE competition (
id_competition varchar() PRIMARY KEY,
name_competition varchar(),
config_competition varchar()
);
This is Association Table (participate a competition)
CREATE TABLE association (
id_association varchar() PRIMARY KEY,
name_association varchar(),
password varchar()
);
This is Player Table (registered by Association to participate player in a competition)
CREATE TABLE player (
id_player varchar() PRIMARY KEY,
name_player varchar()
);
You need to use foreign keys to refer to another table's primary keys. In that way, you can build a relationship between tables. In other words, you can connect the tables that have relationships with each other.
I can suggest you use MySQL workbench and draw an ER diagram of your project in the first phase of your project. After that, you can create a database.
Also, before all these work, you may need to look at the relational data models, one-to-many, one-to-one, and many-to-many. Then you can select the appropriate relations between tables.
For your second question below is an answer:
CREATE TABLE category (
category_id int PRIMARY KEY,
category_name varchar(),
);
CREATE TABLE competition (
id_competition varchar() PRIMARY KEY,
name_competition varchar(),
category_id int FOREIGN KEY REFERENCES category(category_id)
);
I'm not sure how to store or insert this data. I am using PHP and MySQL.
Let's say we're trying to keep track of people who enter marathons (like jogging or whatever). So far, I have a Person table that has all my person information. Each person happens to be associated with a unique varchar(40) key. There is a table for the marathon information (Marathon). I receive the person data in an CSV that as about 130,000 rows and import that into the database.
So - now the question is... how do I deal with that association between Person and Marathon? For each Marathon, I get a huge list of participants (by that unique varchar key) that I need to import. So... If I go the foreign key route, it seems like the insert would be very heavy and cumbersome to look up the appropriate foreign key for the person. I'm not even sure how I would write that insert... I guess it would look like this:
insert into person_marathon
select p.person_id, m.marathon_id
from ( select 'person_a' as p_name, 'marathon_a' as m_name union
select 'person_b' as p_name, 'marathon_a' as m_name )
as imported_marathon_person_list
join person p
on p.person_name = imported_marathon_person_list.p_name
join marathon m
on m.marathon_name = imported_marathon_person_list.m_name
There are not a lot of marathons to deal with at one time. There a lot of people, though.
--> Should I even give the person an ID and require all the foreign keys? or just use the unique varchar(40) as the true table key? But then I would have to join tables on a varchar and that's bad. A marathon can have anywhere from 1k to 30k participants.
--> Or, I could select the person info and the marathon info from the database and join it with the marathon_person data in PHP before I send it over to MySQL.
--> Or, I guess, maybe make a temporary table, then join in the db, then insert (through PHP)? It's been already strongly suggested that I do not use temporary tables ever (this is a work thing and this isn't my database).
Edit: I am not sure on what schema to use because I'm not sure if I should be using foreign keys or not (purpose of this whole post is to answer that question) but the basic design would be something like...
create table person (
person_id int unisgned auto_incrememnt,
person_key varchar(40) not null,
primary key (person_id),
constraint uc_person_key unique (person_key)
)
create table marathon (
marathon_id int unisgned auto_incrememnt,
marathon_name varchar(60) not null,
primary key (marathon_id)
)
create table person_marathon (
person_marathon_id int unsigned auto_increment,
person_id int unsigned,
marathon_id int unsigned,
primary key (person_marathon_id),
constraint uc_person_marathon unique (person_id, marathon_id),
foreign key person_id references person (person_id),
foreign key marathon_id references marathon (marathon_id)
)
I'm going to repeat the actual question really quick.... If I choose to use a foreign key for person, how do I import all the person_marathon data with the person_id in an efficient way? The insert statement I included above is my best guess....
The person data comes in a CSV of about 130,000 rows so that is a straight import into the person table. The person data comes with a unique varchar(40) for each person.
The person_marathon data comes in a CSV for each marathon, as a list of 1,000 to 30,000 unique varchar(40)'s that represent each person who participated in that marathon.
Summary: I am using PHP. So what is the best way to write the insert/import of the person_marathon data if I am using foreign keys? Would I have to do it like the insert statement above or is there a better way?
This is a many-to-many relationship, one person can enter many marathons, one marathon can be entered by many persons. You need additional table in your data model to track this relation, for example:
CREATE TABLE persons_marathons(
personID int FOREIGN KEY REFERENCES Persons(P_Id),
marathonID int FOREIGN KEY REFERENCES Marathons(M_Id)
)
This table uses foreign key constraints. The foreign key constraint prevents from inserting bad data (for example you cannot insert a row with personID = 123 when there is no such id in Persons table), it prevents also from deletes that would destroy a link between tables (for example you cannot delete a person X when exists a record in person_marathon table witth such personID).
If this table contains the following rows:
personID | MarathonID
----------+-----------
2 | 3
3 | 3
2 | 8
3 | 8
it means that persons 2 and 3 both entered marathons 3 and 8
I'm fairly new to PHP and MySQL.
I have two tables as follows:
1.`users`: `id`//primary key
: `name`//user's name
2.`events`: `u_id`//index key and foreign field to users' id
: `u_name`
A user will input an id in a form. That id will be searched in the users table and the relevant details will be taken and inserted in the events table.
I've created the foreign fields and and till now I made a function that took id as a variable and returned details from the users tables as variables which I then inserted in the events table. But then, it meant using "a lot" of variables and I thought what was the use of foreign field.
I'm still learning PHP and don't know how to find and insert using FOREIGN fields from one table to another. I just know how to create foreign fields. Please help.
Is this what you're talking about?
This is how foreign key is created.
CREATE TABLE parent (id INT NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE child (id INT, parent_id INT,
INDEX par_ind (parent_id),
FOREIGN KEY (parent_id) REFERENCES parent(id)
ON DELETE CASCADE
);
Apologize if I didn't understand your question
UPDATED
INSERT table1 (col1, col2, col3)
SELECT col1, col2, col3
FROM table2
WHERE col1 = 'xyz'
Hope this helps
You don't need to store the user name in the events table. The point of the foreign key is that you only need to store the user ID in the events table, because that is a REFERENCE to the user.
To get the user name for an event, say event number 6, you would do
select name from users join events on users.id = events.u_id where events.id = 6
So, you should not be trying to insert user data into the events table. Just put the ID in there, and the user data will be available for you to retrieve using the foreign key.
In MySQL, is it possible to have a column in two different tables that auto-increment? Example: table1 has a column of 'secondaryid' and table2 also has a column of 'secondaryid'. Is it possible to have table1.secondaryid and table2.secondaryid hold the same information? Like table1.secondaryid could hold values 1, 2, 4, 6, 7, 8, etc and table2.secondaryid could hold values 3, 5, 9, 10? The reason for this is twofold: 1) the two tables will be referenced in a separate table of 'likes' (similar to users liking a page on facebook) and 2) the data in table2 is a subset of table1 using a primary key. So the information housed in table2 is dependent on table1 as they are the topics of different categories. (categories being table1 and topics being table2). Is it possible to do something described above or is there some other structural work around that im not aware of?
It seems you want to differentiate categories and topics in two separate tables, but have the ids of both of them be referenced in another table likes to facilitate users liking either a category or a topic.
What you can do is create a super-entity table with subtypes categories and topics. The auto-incremented key would be generated in the super-entity table and inserted into only one of the two subtype tables (based on whether it's a category or a topic).
The subtype tables reference this super-entity via the auto-incremented field in a 1:1 relationship.
This way, you can simply link the super-entity table to the likes table just based on one column (which can represent either a category or a topic), and no id in the subtype tables will be present in both.
Here is a simplified example of how you can model this out:
This model would allow you to maintain the relationship between categories and topics, but having both entities generalized in the superentity table.
Another advantage to this model is you can abstract out common fields in the subtype tables into the superentity table. Say for example that categories and topics both contained the fields title and url: you could put these fields in the superentity table because they are common attributes of its subtypes. Only put fields which are specific to the subtype tables IN the subtype tables.
If you just want the ID's in the two tables to be different you can initially set table2's AUTO_INCREMENT to some big number.
ALTER TABLE `table2` AUTO_INCREMENT=1000000000;
You can't have an auto_increment value shared between tables, but you can make it appear that it is:
set ##auto_increment_increment=2; // change autoinrement to increase by 2
create table evens (
id int auto_increment primary key
);
alter table evens auto_increment = 0;
create table odds (
id int auto_increment primary key
);
alter table odds auto_increment = 1;
The downside to this is that you're changing a global setting, so ALL auto_inc fields will now be growing by 2 instead of 1.
It sounds like you want a MySQL equivalent of sequences, which can be found in DBMS's like PosgreSQL. There are a few known recipes for this, most of which involve creating table(s) that track the name of the sequence and an integer field that keeps the current value. This approach allows you to query the table that contains the sequence and use that on one or more tables, if necessary.
There's a post here that has an interesting approach on this problem. I have also seen this approach used in the DB PEAR module that's now obsolete.
You need to set the other table's increment value manually either by the client or inside mysql via an sql function:
ALTER TABLE users AUTO_INCREMENT = 3
So after inserting into table1 you get back the last auto increment then modify the other table's auto increment field by that.
I'm confused by your question. If table 2 is a subset of table 3, why would you have it share the primary key values. Do you mean that the categories are split between table 2 and table 3?
If so, I would question the design choice of putting them into separate tables. It sounds like you have one of two different situations. The first is that you have a "category" entity that comes in two flavors. In this case, you should have a single category table, perhaps with a type column that specifies the type of category.
The second is that your users can "like" things that are different. In this case, the "user likes" table should have a separate foreign key for each object. You could pull off a trick using a composite foreign key, where you have the type of object and a regular numeric id afterwards. So, the like table would have "type" and "id". The person table would have a column filled with "PERSON" and another with the numeric id. And the join would say "on a.type = b.type and a.id = b.id". (Or the part on the "type" could be implicit, in the choice of the table).
You could do it with triggers:
-- see http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id
CREATE TABLE sequence (id INT NOT NULL);
INSERT INTO sequence VALUES (0);
CREATE TABLE table1 (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
secondardid INT UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (id)
);
CREATE TABLE table2 (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
secondardid INT UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (id)
);
DROP TRIGGER IF EXISTS table1_before_insert;
DROP TRIGGER IF EXISTS table2_before_insert;
DELIMITER //
CREATE
TRIGGER table1_before_insert
BEFORE INSERT ON
table1
FOR EACH ROW
BEGIN
UPDATE sequence SET id=LAST_INSERT_ID(id+1);
NEW.secondardid = LAST_INSERT_ID();
END;
//
CREATE
TRIGGER table2_before_insert
BEFORE INSERT ON
table2
FOR EACH ROW
BEGIN
UPDATE sequence SET id=LAST_INSERT_ID(id+1);
NEW.secondardid = LAST_INSERT_ID();
END;
//
I am new to php and mysql. I created a database named 'students' which contain two tables as 'student_details' which have fields like 'ID, Name, Age, Tel#, Address' and another table as 'fee_details' which have fields like 'ID(student_details table ID), Inst Id, Date, Receipt No'.
I want to set a foreign key and retrieve data from both tables when a student paid their fees and if a student passed out or discontinued I want a delete option to delete his all records from my tables. So please help me to solve this by PHP code and displays it in HTML while using a search form.
Enforcing referential integrity at the database level is the way to go. I believe when you said you wanted the delete "to delete his all records from my tables" you meant deleting the row and all its child records. You can do that by using foreign keys and ON DELETE CASCADE.
CREATE TABLE students
(
student_id INT NOT NULL,
name VARCHAR(30) NOT NULL,
PRIMARY KEY (student_id)
) ENGINE=INNODB;
CREATE TABLE fee_details
(
id INT,
date TIMESTAMP,
student_id INT,
FOREIGN KEY (student_id) REFERENCES students(student_id)
ON DELETE CASCADE
) ENGINE=INNODB;
With this, when a student is deleted from the students table, all its associated records will be deleted from fee_details.
you can try mysql_query() and mysql_assoc_array()