I have a table that stores orders.
id (auto increment) an oid (not auto incremented) and then the order details.
some orders can have multiple entries, this is why i have an ID and an Oid(order id)
so if you order 3 xwidgets and 4Zwidgets they go under the same OID
I am using the following code to assign the next OID number and am wondering if this is the best way:
$maxquery = mysql_query("SELECT MAX(oid) FROM ordr") or die(mysql_error());
$maxresult = mysql_fetch_array($maxquery);
$maxid = $maxresult['MAX(oid)'];
$oid = $maxid + 1; -- this gives me a new OID for the next entry since i can not auto increment this column
You probably want to use auto-increment columns. This will let you insert the data, and MySQL will pick an index for you. You'll need to denormalize your data to do this though.
You'll want two tables: orders and order_items, where:
orders
------
order_id
[any other columns]
order_items
-----------
item_id
order_id
[any other columns]
Insert the order into the orders table with a NULL order_id and record the order_id that MySQL sets. Now insert the order_item using the order_id you have, and let it auto-generate the item_id.
This way, MySQL will generate the numbers, so you don't need to worry about two orders trying to use the same order ID. Also, any order information won't be duplicated for each item in the order.
Related
My tables are :
orders(orderID,orderDesc)
orderscoding(orderscodingID,orderID,codeA)
I have around 230 records for both tables.
I want to alter the (orderID) auto-increment from
1,2,3,4,5 ..... to 100001,10002,10003,10004,10005
and reflect it on the related table , is this possible?
So basically this will not work, as it is for new insert (but I want to modify existing records):
ALTER TABLE orders AUTO_INCREMENT=100001;
If you want to update existing orderIDs, you can do like this
UPDATE orders SET orderID = orderID + 10000
All existing orderID will be incremented by 10000 with this query. So, 1 will become 10001, 2 will be 10002 and so on...
Do the same for orderscoding table to keep it synced with orders table (do the same if any more tables are synced to orderID.)
UPDATE orderscoding SET orderID = orderID + 10000
I have a single-column MySQL database table ids (id INTEGER PRIMARY KEY AUTOINCREMENT) where I store pre-generated unique ids in an ascending order. In order to get a random id from that table I use this query:
SELECT id FROM ids ORDER BY RAND() LIMIT 1;
And now I am wondering how to ensure that the id I got is never used again. I see two options. One is to delete the id from the table and the other is add a column tracking the use of that id:
DELETE FROM ids WHERE id=?; //where id is the one I got from the previous query
or
SELECT id FROM ids WHERE used=0 ORDER BY RAND() LIMIT 1;
UPDATE ids SET used=1 WHERE id=?; //where used is new column with 0 as default value
There is only a slight problem with both of these. If the server load is heavy then two queries for a random id might return the same id before it gets removed from the list (or disabled with used column).
Would transaction help?
Wrapping your select and your update in a transaction will work. If you want to avoid a transaction as well as the race condition between selecting your item and marking it unusable, you can run the UPDATE first. You'll need a way for each of your processes to identify itself as the owner of the row between claiming it and deletion. For example, assume your ids schema is
id (integer)
owner (string)
Have each process pick a UUID (or something else suitably unique) and run the following:
UPDATE ids SET owner = $process_id WHERE owner IS NULL ORDER BY RAND() LIMIT 1
SELECT id FROM ids WHERE owner = $process_id
DELETE FROM ids WHERE id = $selected_id (or otherwise mark it used)
Step 1 atomically claims the row for the process so that no other process can claim it. Step 2 pulls out the claimed ID. Step 3 removes the ID from the available set for good. If Step 3 doesn't delete the row, just marks it used, make sure you clear owner as well so your process won't select it again later.
Add an extra column to your ids table. Let us say selected. You will update this column when it is generated in your randomized query.
1 for selected and 0 for not yet.
For example
SELECT id FROM ids ORDER BY RAND() WHERE selected = 0 LIMIT 1;
$id = $row['id']; /* STORE THE SELECTED ID TO A VARIABLE */
Then update the table with
UPDATE ids SET selected = 1 WHERE id = $id
So that your next run of your randomized query will only get the row of selected 0 value, and not the one with 1 value.
you could try updating the id 1st before selecting it. try this one.
-- get firstID
SELECT #MinID:=id FROM ids ORDER by id ASC LIMIT 1;
-- get last id
SELECT #MaxID:=id FROM ids ORDER by id DESC LIMIT 1;
-- get random id
SELECT #rndomID :=ROUND((RAND() * (#MaxID-#MinID))+#MinID);
-- update first
UPDATE ids SET used=1 WHERE id=#rndomID;
-- select the id
SELECT id FROM ids WHERE used=0 WHERE id=#rndomID;
i want to fetch all record from MySQL database table using PHP without last added record
I have 4 Columns in the Table, ID(auto) & title and message.
You can use this, if as you say, ID is auto_increment
$sql = "SELECT * FROM table WHERE ID != (SELECT MAX(ID) FROM TABLE) ORDER BY ID";
This is selecting all the records from your table, ordered by id, where the id is not the biggest one.
I think most people had serious problems with inserting a value/data into a database (mysql). When I'm inserting a value into a database, I assign an unique id (INT) for that line. When I query the database, easily I can read/modify/delete that line.
With function for() (in php) I easily can read values/data from the database. The problem occurs when I delete a line (in the middle for example).
E.g:
DB:
ID | column1 | column2 | ... | columnN
--------------------------------------
1 | abcdefgh | asdasda | ... | asdasdN
2 | asdasddd | asdasda | ... | asdasdN
...
N | asdewfew | asddsad | ... | asddsaN
php:
for($i = 0; $i <= $n; $i++){
$sql = mysql_query("SELECT * FROM db WHERE ID = '$i' ");
//Code;
}
*$n = last column value from ID
Am I need to reorganize the entire database to have a correct "flow" (1, 2, 3, .. n)? Or am I need to UPDATE the each cell?
What you're doing here is unnecessary thanks to AUTO_INCREMENT in mysql. Run this command from PhpMyAdmin (or another DB management system):
ALTER TABLE db MODIFY COLUMN ID INT NOT NULL AUTO_INCREMENT;
Now when insert a row into db mysql will assign the ID for you:
INSERT INTO db (id, column1, column2) VALUES(NULL, 'abc', 'def');
SELECT * FROM db;:
+--+-------+-------+
|id|column1|column2|
+--+-------+-------+
|1 |old |oldrow |
+--+-------+-------+
|2 |abc |def | <--- Your newly inserted row, with unique ID
+--+-------+-------+
If you delete a row, it is true that there will be an inconsistency in the order of the ID's, but this is ok. IDs are not intended to denote the numeric position of a row in a table. They are intended to uniquely identify each row so that you can perform actions on it and reference it from other tables with foreign keys.
Also if you need to grab a group of ID's (stored in an array, for example), it is much more efficient to perform one query with an IN statement.
$ids = array(1,2,3,4,5,6);
$in = implode(',', $ids);
mysql_query('SELECT * FROM db WHERE id IN ('.$in.')');
However, if you want all rows just use:
SELECT * FROM dbs;
But be weary of bobby tables.
You can select all the rows with query
SELECT * FROM db
and do whatever you want after
You can never ensure, that the ids are continous. As you noticed yourself there are gaps after you delete a row, but even for example when you insert rows within a transaction and don't commit it, because something failed and you need to revert the transaction. An ID is an identifier and not row number.
For example if you want to select X items from somewhere (or such) have a look at LIMIT and OFFSET
SELECT * FROM mytable ORDER BY created DESC LIMIT 10 OFFSET 20;
This selects the rows 21 to 30 ordered by their creation time. Note, that I don't use id for ordering, but you cannot rely on it (as mentioned).
If you really want to fetch rows by their ID you definitely need to fetch the IDs first. You may also fetch a range of IDs like
SELECT * FROM mytable WHERE id IN (1,2,3,4);
But don't assume, that you will ever receive 4 rows.
Ids are surrogate keys–they are in no way derived from the data in the rest of the columns and their only significance is each row has a unique one. There's no need to change them.
If you need a specific range of rows from the table, use BETWEEN to specify them in the query:
SELECT id, col1, col2, ..., coln
FROM `table`
WHERE id BETWEEN ? AND ?
ORDER BY id
If you need all the rows and all columns for that table use:
$query = mysql_query("SELECT * FROM table_name");
and then loop through each row with a while statement:
while ($row = mysql_fetch_array($query ))
{
echo $row['column_name'];
}
You do not have to reorganize the entire database in order to keep the index. But if you feel like it, you'd have to update each cell.
BTW, look at mysql_fetch_array(), it will ease the load on the SQL server.
tbl_product
Name | Creator | UID | Salerank
tbl_price
Supplier | Price | UID
I want to insert a product and then insert multiple prices into a seperate table. How is it possible to ensure that both tables had the same UID ideally an auto increment field? I will be using PHP alongside MySQL.
Thanks,
J
Make UID an auto_increment primary key on the products table, but just a regular primary key on the prices table (no auto_increment). After you insert itnto products, use the PHP command mysql_insert_id(). This will get the ID generated from the last query, which will be your UID generated on the products table. Assign it a variable and use it in your insert statement on the prices table.
http://php.net/manual/en/function.mysql-insert-id.php
Use a GUID for the UID, or better, insert your products and the insert the prices using e.g. the name of the product (assuming unique) to look up the relevant product UID.