I have an application which keeps database of all nearby restaurants.
When adding a new entry, there is an option to add a few images of your restaurant.
Now the problem:
I'd like to sort the different restaurant images into separated folders, named by restaurant id stored in mysql auto increment ID. The only problem here is, that i dont know that id in advance.
Form example:
text input - title
text input - address
text input - phone
file input - image
file input - image
So, what should I do now?
I. Get the last id, lock the table, create folder named by id, store images inside, store information to mysql database including image paths, unlock table.
or
II. Store all information excluding images paths to mysql database, use PHP mysql_insert_id, create folder named by id, store images inside and store images paths to mysql database.
or
III. Better solution?
This kind of thing is usually done with your option II. Store in the database the main row of information, get the last insert id via mysql_insert_id() or the native MySQL LAST_INSERT_ID() function, then proceed to store rows in any related tables if necessary and create the image directory to store filesystem data.
Assuming the image paths you intend to store in the database will go into a different table with a one-to-many relationship back to the main restaurant table, you'll need to know the last insert id to insert them anyway. Don't worry much about doing it in multiple operations -- that's exactly the reason most RDBMS have a function like LAST_INSERT_ID().
If you are using the autoincrement column. You can right after your insert statement call the last_insert_id() function to retrieve the id of the last inserted record.
See this link for documentation:
http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id
Its important that you do this within the same transaction/connection otherwise the value might be erroneous.
I don't see a need to use the restaurant's id to organize the pictures - especially since you get into the timing issues you describe. I'd create another unique id - call it picture_folder_id or something - and use that to name the folder for the pictures. As long as you enforce uniqueness on that id, you won't get any collisions, and you won't have any timing problems or locks.
Related
I have two MySQL databases. I would like to data from one database to another. Both have the same structure and entries except that one database has same IDs for different items within the same tables. I don't want to replace the data from the old to the new database. If IDs are there, I would like the new database to skip it. If it's a duplication, I would like a new ID to be generated.
I'd like to use phpmyadmin for this but have no idea if this is even possible.
0.) Make backup of both tables
PHPMYADMIN will be sufficient for your request.
First you need to ensure there is no duplicating id's or primary keys.
Assuming two tables testtable1 and testtable2 have columns testtable_id, name
1.) firstly you would make query on second table
UPDATE testtable2 SET testtable2.testtable_id = testtable2.testtable_id + (SELECT MAX( testtable1.testtable_id ) FROM testtable1);
2.) Than, again in testtable2, there is tool Copy table to (database.table): under Operations menu, set DB name and testtable1 name (db name should be already set), select Data only radio button option and click Go. 3.) Now, you have all data from both tables in testtable1.
Edit. Firstly I thought it is matter of two tables in same database. But nevertheless you can use step two for rest of the tables too. Just set correct DB and table name in step two. Also, before that, set query so expecting ID to be higher than MAX ID of table you want to extend. You can hard code parenthesis part with exact number of MAX ID first DB corresponding table.
I have a table called users and a table called pages. Users of the system can subscribe to a page and receive updates about the page. My problem is that users and pages will be updated dynamically (ie. no manual intervention to the tables) and I don't want to keep adding another column everytime someone subscribes to the page.
How can I achieve updating both the users table and the pages table dynamically to reflect that they have subscribed to that page?
My idea would be to add an comma separated array of usernames into the pages table and update them as users subscribe/unsubscribe.
Just making it an official answer:
While the initial hunch may be to use comma separated values to represent the link between those 2 tables (or any other way of saving the data in one column like saving a json string), it is actually bad practice because it does not conform to the First Normal Form (and definitely not 2nd and 3rd).
First Normal Form - Wikipedia
First Normal Form says you should never store more than 1 value in 1 table cell.
The problem, in short, starts when you'll need to use that data, which will actually take you at least 2 actions - 1 is reading the data from the database and 2nd is to parse it in your languaging script. Imagine what happens when you need then to use that data to read some other data from the database - you are making more sql queries than you need and taking at least twice the time (+resources). It becomes even more complicated when you need to use JOIN queries or have other one-to-many data relationships.
The solution then is simple - you need to create a 3rd table that serves as an intermediate table.
You can call it users_pages or user2pages and that represents the 1 to many relationship between 1 user and many pages.
The structure of the table is as simple as:
users_pages
-----------
-- id // a unique id for the relationship, can be auto generated
-- user_id // the user id
-- page_id // the page id
-----------
This allows you to build a more robust application as well as run advanced queries and calculations without the need to parse the data in your script (i.e count amount of pages each user is subscribed to, or amount of users subscribed to 1 page).
Unsubscribing can be also much easier this way since you don't need to read the users or pages table at all. You simply delete the relation from the users_pages table.
Without it, you will need to (a) first read the users table (b) get the pages data comma separated (c) parse the data and remove the specific page from it (d) save the new data again to the database. That's 4 actions and 2 SQL queries...
I hope this helps!
When creating a many to many table, relational database. If for example you are enabling users to scrape images form around the web and tag them.
Would it be better to:
Check to see if the image is already in the database and if it is, create a link in a relational table and if it is not create a new image.
Create a unique instance of the image for every user and when looking to display the most popular images SELECT AND ORDER BY the image with the most duplicates
I hope this makes sense. Thanks in advance for you help.
I assume you have something equivalent to a USERS table and a PICTURES table. Also a table to break up the many to many relationship. U2P I will call it.
The option you listed as option 1 would seem to be the preferred way. Check to see if the picture is in the DB, if it is get primary key from PICTURES corresponding to it. If not, put the picture in the PICTURES table.
Regardless of if it is a new image, or one that is already in there, you will insert the event into the U2P table. This would reference the USERS primary key and the PICTURES primary key corresponding to the event. You would also record other data such as time etc...
I have two tables in my database 'file' and 'message'. If a user submit a file I first submit the file name in the file table, location and so on in my database. After that I inmedietley set the following variable:
$file_id = mysql_insert_id();
This will get the assigned id of the the file, with that variable I can the insert it into the message table, such as message_file_id. That way I can get message file, with just an id.
All is working, but my question is. If I were to have 2 users submit a message with a file at the same time (which would be hard, or even impossible) is there a possibility user A gets user B file id?
There is variable that could affect this like a user having faster or slower time than another.
No, there is no chance User A will get User B's file ID as long as both transactions were performed in the same connection. MySQL is smart enough to give out distinct auto-increment IDs to different connections, even if they are inserting into the same table concurrently. You don't even have to wrap the two inserts in a transaction.
So there is no problem at all as long as you're using mysql_insert_id() - it will always work as you would expect it to and won't mix up IDs, and you are completely safe to use the return value from mysql_insert_id as a the foreign key in a record related to the one you have just inserted.
http://dev.mysql.com/doc/refman/5.0/en/mysql-insert-id.html
I need to know the id (and reserve it) for a record that I will insert in database before insert it because I add a product and upload also a image for this product, and the location of image is related to the product id.
I can find the id that will follow, but I need also to keep it "lock" until the product image is uploaded, to be sure that this id isn't used by another user meanwhile.
You can split this into two operations.
In the first you create everything for the product and get the id. In the second you update the row with the image you've uploaded, which can now be saved since you know the ID.
you can do it as a transaction
I googled "php mysql transaction" and there are a lot of tutorials on how to do this
http://www.linuxdig.com/news_page/1079394922.php
id reservation can only be done safely if you have your own auto increment implementation. Even when running in a transaction, you can not know for sure what the next id is. You just can be sure what you have when you requested for it.
Some people use the mysql_insert_id to receive the last inserted id. But I have somewhere in mind this function is not threadsafe and you'll probably get the id of another thread which just inserted.
However, in your case only two options come to my mind:
1) create your own sequence generator
2) insert your datarow, select it again with all values in the where clause, and use that id. Run option 2 in a transaction (as already suggested above)
I would go for option 1. Sequence generation is commonly used with all other databases (from the widely used only mysql supports auto increment as far as I know). Sequences therefore are fully acceptable.
Cheers, Christian