Insert different UUID on each row of a large table - mysql

I have a table with ~80k rows with imported data. Table structure is as follows:
order_line_items
- id
- order_id
- product_id
- quantity
- price
- uuid
On import, the order_id, product_id, quantity, and price were imported, but the uuid field was left null.
Is there a way, using mysql's UUID() function, to add a uuid to each row of the table in bulk? I could use a script to cycle through each row and update it but if there is a MySQL solution, that would be fastest.

Each call to uuid() returns a different, unique value.
So a simple
UPDATE order_line_items SET uuid = uuid();
should assign each uuid field a unique value.
Edit March 2022
Note that using this method only a few characters change in the uuids, which make them look identical at a glance, but actually they're all different.
*Edit June 2020*
With #RickJames (see comments) we are trying to comprehend how some people can get the same UUID after running the Update command above (they should be all different).
MySQL/MariaDB. The question is tagged mysql ; be sure you are running MySQL or MariaDB, as another DBMS might not render that MySQL behavior for the UUID() on multiple rows
Perform the Update as shown here, UUID() is a MySQL function (thus the ())
Check the field that receives the Update, it must be large enough to hold 36 chars
See also this related question on DBA SE.

Related

How to skip mysql table update if previous row is identical based on certain columns

I'm inserting data into a mysql table via a php script, however I wanted to know if there is a better way to insert data if the previous row is not identical.
For example:
Stock Price Bid Ask Timestamp
AAPL 232.23 232.22 232.23 1879239289
TSLA 500.23 500.12 500.26 1879239346
If the next record for aapl is identical to the most recent record of aapl. I don't want to insert it.
Likewise with TSLA.
I know I can do a query before insert, sort by id desc, and check each column - but is there another way using mysql trigger or condition?
Make the ID as primary key in MySQL and into the php code create the query between try catch.
https://stackify.com/php-try-catch-php-exception-tutorial/

MySQL LAST_INSERT_ID() question potential

If i have insert query for example:
INSERT INTO user(username) VALUES('admin');
And then get the id of the inserted record with
LAST_INSERT_ID();
Looks find but what happens if between the insert and LAST_INSERT_ID() another insert is executed.
How MySQL knows to return the correct id (for the first or second insert) since no parameter is passed to LAST_INSERT_ID();
Is it save to use this function?
Thanks
I'm supposing that you mean what happen if i'm connected to the MySQL server and executing an INSERT but others are also doing insert, like updating a table on a website while client are currently using it.
If you go take a look at the documentation https://dev.mysql.com/doc/refman/8.0/en/information-functions.html there is a point that answers your questions:
The ID that was generated is maintained in the server on a
per-connection basis. This means that the value returned by the
function to a given client is the first AUTO_INCREMENT value generated
for most recent statement affecting an AUTO_INCREMENT column by that
client. This value cannot be affected by other clients, even if they
generate AUTO_INCREMENT values of their own. This behavior ensures
that each client can retrieve its own ID without concern for the
activity of other clients, and without the need for locks or
transactions.
This should be the same in MariaDB.
As discussed in the comment, you are wondering if you can use this in a php PDO environment. If you mean to use this directly from the database, it's a no, you won't be able to have the last inserted ID because you won't have the same client connection as PDO. If you want to use it directly from PDO please use the specific PDO function: http://php.net/manual/fr/pdo.lastinsertid.php , this should allow to do what you want.
If you insert multiple rows into a table using a single INSERT query, the LAST_INSERT_ID function returns the last insert id of the first row.
i.e
If your table id has 3 as column value and you will insert 4 rows in a single query then LAST_INSERT_ID will give you 4 instead of 7
If you insert 4 rows in 4 different insert query then LAST_INSERT_ID will give you 7
last_insert_id( ) Or mysqli_insert_id( ) will always return the id of last or most recent query. And also be noted that id field must have AUTO_INCREMENT enabled.
It doesn't give you the freedom to choose any specific table. Or you can't have id which is generated from your previous query.
So, from this point it serves a very small purpose. Only the last id, it doesn't matter which table.
To get last id from any specific table this query would be helpful : "SELECT id FROM table_name ORDER BY id DESC LIMIT 1"

mySQL valid bit - alternatives?

Currently, I have a mySQL table with columns that looks something like this:
run_date DATE
name VARCHAR(10)
load INTEGER
sys_time TIME
rec_time TIME
valid TINYINT
The column valid is essentially a valid bit, 1 if this row is the latest value for this (run_date,name) pair, and 0 if not. To make insertions simpler, I wrote a stored procedure that first runs an UPDATE table_name SET valid = 0 WHERE run_date = X AND name = Y command, then inserts the new row.
The table reads are in such a way that I usually use only the valid = 1 rows, but I can't discard the invalid rows. Obviously, this schema also has no primary key.
Is there a better way to structure this data or the valid bit, so that I can speed up both inserts and searches? A bunch of indexes on different orders of columns gets large.
In all of the suggestions below, get rid of valid and the UPDATE of it. That is not scalable.
Plan A: At SELECT time, use 'groupwise max' code to locate the latest run_date, hence the "valid" entry.
Plan B: Have two tables and change both when inserting: history, with PRIMARY KEY(name, run_date) and a simple INSERT statement; current, with PRIMARY KEY(name) and INSERT ... ON DUPLICATE KEY UPDATE. The "usual" SELECTs need only touch current.
Another issue: TIME is limited to 838:59:59 and is intended to mean 'time of day', not 'elapsed time'. For the latter, use INT UNSIGNED (or some variant of INT). For formatting, you can use sec_to_time(). For example sec_to_time(3601) -> 01:00:05.

MySQL to Postgres data migration

I'm in the process of migrating a Ruby on Rails application from MySQL to Postgres. Is there a recommended way to keep the deleted data, like all the deleted records (their IDs at least) from MySQL?
In testing a dump-and-restore didn't seem to keep deleted records.
Also, in the event that I manage to keep the records where they are, what'll happen with the blank ones in Postgres? Will they be skipped over or used?
Example
Say I have a user with an ID of 101 and I've deleted users up to 100. I need 101 to stay at 101.
So you don't want to reassign the IDs assigned to records where you generated keys.
That should be the default in any sane migration. When you copy the data rows over - say, exporting from MySQL with SELECT ... INTO OUTFILE and importing into PostgreSQL with COPY tablename FROM 'filename.csv' WITH (FORMAT CSV), the IDs won't change.
All you'll need to do is to set the next ID to be generated in the sequence on the PostgreSQL table afterwards. So, say you have the table:
CREATE TABLE users
(
id serial primary key,
name text not null,
...
);
and you've just copied a user with id = 101 into it.
You'll now just assign a new value to the key generation sequence for the table, e.g.:
SELECT setval('users_id_seq', (SELECT max(id) FROM users)+1);
To learn more about sequences and key generation in PostgreSQL, see SERIAL in the numeric types documentation, the documentation for CREATE SEQUENCE, the docs for setval, etc. The default name for a key generation sequence is tablename_columnname_seq.

MySQL select after insert

Lets asume a table like:
ID = INT, AutoIncrement
VAR = VARCHAR, 65
FOO = VARCHAR, 65
I want to insert something new, and get the Auto-Generated ID, for further use.
My current solution is:
1.INSERT into table (VAR,FOO) VALUES ('test','anothertest')
2.SELECT * FROM table ORDER BY ID LIMIT 1
To get the last insert, but the problem is, what happends if the website lags, and there is a time gap between the queries?
example:
12:00AM 0.000s -> "INSERT into table (VAR,FOO) VALUES ('test','anothertest')
12:00AM 0.500s -> "INSERT into table (VAR,FOO) VALUES ('xyz', '!!!!!)`
12:00AM 0.800s -> "SELECT * FROM table ORDER BY ID LIMIT 1
the Query in 3 would not return the ID from 1, it would return the ID from 2
My Question no is, is there an absolute secure way to get a Value from a inserted Query?
like a confirmation "test, anothertest has successfully inserted into table, ID is 20"
the ID should be available as variable in php, just for information
Since you mention PHP there is usually a specific function to get that. If you are using the mysqli drivers then see mysqli_insert_id
Edit: According to the docs linked above The value of the AUTO_INCREMENT field that was updated by the previous query. Returns zero if there was no previous query on the connection or if the query did not update an AUTO_INCREMENT value. Since it is talking about queries on the connection then I would interpret that as meaning that queries on other connection (i.e. queries from other requests) won't affect the value returned. As long as you call it dirctly after the insert (before you do anythign else) then it should work.
Caveat: I am simply interpreting the docs here. I haven't actually tested for other calls myself. Wouldn't be that difficult though - simply have a script which does an insert, a sleep then fetches the ID, giving you time to do another insert during the sleep.
In php I use mysql_insert_id();
In later MySql insert/update I use LAST_INSERT_ID()
It's absolutely the same.
Try using, Scope_Identity(). This returns the last autogenerated id.
This link has more info: http://msdn.microsoft.com/en-us/library/ms190315.aspx