Right now I'm trying to query a table that holds the id of two tables that holds the id to two other tables (where one of these holds the id to other tables)
Hell, I know.
As I am a beginner in SQL, how do I go about efficiently querying this to get all the details of each table? As of now i only see a very long set of Select statements. Here is how the tables are set up below
I am not sure what you are asking.
If you need a SELECT command it would have 2 INNER joins. But, if you are asking to get all the info (and children) then it would need more INNER joins. OR if you are using a persistent client for your application.... I just don't know. Because it is incomplete data to do it.
Related
I understand some basics about relational database. But I don't get the point of making relation through phpmyadmin designer. What is the benefit there when I have to query any related table with another table's content ID?
When I make any query to select post where user_id=1, is there any way to make it like that, I will select from user_list where id=1, and I don't have to make another query to table posts?
To answer the first question: It documents the relationships for reference, and most designer applications will generate constraints enforcing those relationships.
To your answer your second question, no. If you only want information from posts, there would be no reason to involve users_list unless it relied on information from there, such as wanting to know "posts made by any users with the first name 'bob'"; in which case you would use a join. But if you already know the id for the user, there is no reason to involve users_list.
I have two tables in mysql. When I insert/delete values in the first table I want that the values get duplicated in table 2 to keep them "aligned".
table1:
id - username
1 - test_user
table2:
Same id as table1 and username as table1 (on insert/delete)
I want to keep the data between the tables aligned without doing multiple queries. I've read about triggers not sure if it's the correct road, i am a beninner.
I said two tables but i will need to do this in multiple tables.
You can use Mysql triggers. This way you can auto insert/update/delete datas from second table.
MySql Using Triggers
When you INSERT new records, given that you don't want to do two inserts for some reason, using a trigger to insert into the second table will work. For UPDATE and DELETE you might want to look at the CASCADE option with foreign keys. If all you are doing is keeping the data consistent between tables, that's exactly what cascade is for.
When you create table2 you just add a foreign key like this:
FOREIGN KEY (id, username)
REFERENCES table1(id, username) ON UPDATE CASCADE ON DELETE CASCADE
Then whenever you alter table1 the changes will automatically get pushed through to table2.
Couple prerequisites for this to work:
You have to use a storage engine that supports foreign keys, something like InnoDB and not MyISAM
You need to have an index on (id,username) in table1; the foriegn key needs to match a key in the parent table
You should read the doc page for foreign keys. There are a couple other ways you can tweak them, and you should figure out what works best for your purposes.
You can certainly put triggers on your table1 to make parallel changes to your other tables as your application changes table1.
See here for the documentation: http://dev.mysql.com/doc/refman/5.0/en/trigger-syntax.html
But, you should think over your design. It will take multiple queries to do your inserts and updates; they'll just be done "behind your back" on the server. They'll still take time. Triggers can really slow things down.
Also, triggers are a little bit fragile. If you add a column to a table, you'll have to rework your triggers. Triggers are generally a pain in the neck to keep in a source-control system and a huge pain in the neck to test, so using them will make your application more troublesome to maintain.
Could you think of another approach to handling this need for duplication? Could you, for example, use a view or a join to present the data you need to your application program without actually duplicating tables and the rows in them? If you figure out how to do that you'll be much happier in the long run.
CREATE VIEW table2 AS
SELECT *
FROM table1;
will produce a "fake" table2 with the contents of table1.
Or if you're hoping to view only the test users in a second table, a view can do that for you too, for example:
CREATE VIEW table3 AS
SELECT *
FROM table1
WHERE usertype = 'test_user' ;
If you're using duplicate tables for "backup," that's a bad way to make sure your information is safe. Instead, you need to back up your MySQL server instance.
Formal relational database design principles teach us to duplicating data, but instead use view and joins to structure the data the way applications need to see it.
I have 2 tables users and comments.
In term of performance, should i use a join (with user id) to get the username from users table or should i add a column username to the comments, so i won't need join for only 1 data (username) but i will need to add one more data for each comment (username).
Is join slow if there's a lot of comments in the table ?
Wich one should i do ? Join or add column username to comments.
Thank you.
Join is probably the best so you're not storing data in two places. What if a user name is changed? It won't change the user name for the comments. Also, joining two tables is not very time consuming.
It depends on the number of users and comments. Having a denormalized db, which is what you ask, can be faster but then you need to take care yourself to update username in both tables. Don't forget to add index for userid in comments table if you go the join way.
So the correct answer I believe is go with the join, and denormalize later if needed.
If you're using InnoDB, you can add the column and add foreign key restrictions. This will allow you to increase efficiency and worry less about updating indexes.
The one reason why you would store the user name in the comments table is if you wanted to know the user name when the comment was created. If the user name is subsequently changed, you'll still have the name at the time of the comment.
In general, though, you want to use join. You want to have the primary key on a table defined, probably as an auto-incremented (identity) integer value.
If you are concerned about performance for getting all comments for a single user, then you should build an index on the comments table on the user id field.
Personally I would rather user two simple separate queries. I do not like joins all that much. Joins just produce duplicated data by definition. You might want to check http://www.notorm.com/ that is a simple php db access layer going joinless way.
So I have 2 tables in my database, they are 'workouts' and 'exercises'. Workouts contains a row called exercises which is a comma-separated list of exercise IDs - from the 'exercises' table e.g. '1,2,3'.
My question is, can I write a single query to allow me to select a row from the workouts table, say one with an id of 1, and have MySQL fetch each of the exercises from the list in that row, returning them within the 'workout' row?
At the moment I'm using PHP to select the workout row, and then making individual requests for each of the exercises, resulting in serious inefficiency.
I took a look at Joining rows as array from another table for each row and also did some research into the group_concat() function, but I'm not sure that's what I'm after.
Update
Here are the 2 tables:
IMO, the best approach is to redesign your schema to have a cross-reference table called exercises_workouts (or something similar). Remove the CSV field.
Here's page that goes into more detail on implementing a many-to-many relationship:
http://www.tonymarston.net/php-mysql/many-to-many.html
Note: The linked page uses the mysql_* functions, but the general explanation of the approach stands. You'll want to look into PDO for database access.
I have two tables in the database(videos and viewData) .
Im trying to build a script that runs for each record in the "videos" table and does something using the "videoID" field for that specific entry in the "videos" table. The does something part would be dumping some data into the viewData table.
Would I need to store all the records in an array before calling the loop? An example of a loop like this would be really helpful. Also in a way that could be potentially scalable that wouldn't hurt the server too much if there were a 1000+ records in the "videos" table.
Thanks,
Dave
Try to avoid the loop at all costs. Think set based processing, which means handle the entire set of rows within one SQL command.
I'm not entirely sure what you are attempting to do, as your question is a little vague. however, here are two possibly ways to handle what you are trying to do using set based thinking.
You can do a JOIN in an UPDATE, essentially selecting from the parent table and UPDATEing the child table for all rows in a single UPDATE command.
UPDATE c
SET Col1=p.Col1
FROM ParentTable p
INNER JOIN ChildTable c On p.ParentID=c.ParentID
WHERE ...
you can also INSERT based on a SELECT, so you would create one row from each row returned in the SELECT, like:
INSERT INTO ChildTable
(Col1, Col2, Col3, Col4)
SELECT
p.ColA, p.ColB, 'constant value', p.ColC-p.ColD
FROM ParentTable p
WHERE...
Working with a database in the loop isn't a good practice. It is good to select all table data into an array by one query and work with this array in future.
Do you have access by other means to MySQL tables? Like with MySQL Administrator or another tool, even by command line?
This is because it would be much more time, resources and everything else, doing that directly in the database, through a query or a database function.
I would do that this way.
But for the sake of clarity, unless you are storing the videos themselves inside database tables, 1000 records are not a problem. Maybe 10,000 would be.
General tip: do just what you need to do.
If you only need to operate upon data, do this on the database.
If you only need to check one field in one table, use SELECT your_field FROM your_table instead of SELECT * FROM your_table.