What is the replacement for uniqueidentifier in Mysql - mysql

I have a query from SQL Server which I want to run in Mysql. but I cannot find any replacement for uniqueidentifier keyword from SQL Server script to MYSQL Script.
Here is the query
CREATE TABLE foo(
myid uniqueidentifier NOT NULL,
barid uniqueidentifier NOT NULL
)
What will be the query in Mysql for the same above SQL Server script?

CREATE TABLE FOO (
myid CHAR(38) NOT NULL,
barid CHAR(38) NOT NULL
);
According to MS website, GUID's are 38 chars in length.

The accepted answer, although not exactly wrong, is somewhat incomplete. There certainly are more space efficient ways to store GUID/UUIDs. Please have a look at this question: "Storing MySQL GUID/UUIDs"
This is the best way I could come up with to convert a MySQL GUID/UUID generated by UUID() to a binary(16):
UNHEX(REPLACE(UUID(),'-',''))
And then storing it in a BINARY(16)
If storage space of the GUID/UUID is a primary concern this method will deliver significant savings.

According the MySQL website you should match it to VARCHAR(64)
UNIQUEIDENTIFIER, VARCHAR(64)
http://dev.mysql.com/doc/workbench/en/wb-migration-database-mssql-typemapping.html

Remember also that a 16 byte value is represented in hex as 32 bytes. With the 4 dashes and the 2 curly braces, that gets us the 38 bytes in this format compatible with SQL Server with a 38 byte string. For example: {2DCBF868-56D7-4BED-B0F8-84555B4AD691}.

Related

"Horse Table" in a MySQL database is not working?

I want to create a database with a table with the following criteria and constraints:
ID - integer with range 0 to 65 thousand, auto increment, primary key
RegisteredName - variable-length string with max 15 chars, not NULL
Breed - variable-length string with max 20 chars, must be one of the following: Egyptian Arab, Holsteiner, Quarter Horse, Paint, Saddlebred
Height - number with 3 significant digits and 1 decimal place, must be ≥ 10.0 and ≤ 20.0
BirthDate - date, must be ≥ Jan 1, 2015
So far I have wrote this
CREATE TABLE horse (
ID SMALLINT AUTO_INCREMENT PRIMARY KEY,
RegisteredName VARCHAR(15) NOT NULL,
Breed VARCHAR(20), CHECK (Breed="Egyptian Arab" "Holsteiner" "Quarter Horse" "Paint" "Saddlebred")
Height DECIMAL(3,1) CHECK (Height=>10.0) CHECK (Height<=20.0),
BirthDate DATE CHECK (BirthDate=>"Jan 1, 2015")
);
After reading all of the suggestions and input you provided I corrected my code to be as follows.
CREATE TABLE Horse (
ID SMALLINT ***UNSIGNED*** AUTO_INCREMENT PRIMARY KEY,
RegisteredName VARCHAR(15) NOT NULL,
Breed VARCHAR(20) CHECK (Breed="Egyptian Arab" "Holsteiner" "Quarter Horse" "Paint" "Saddlebred")***,***
Height DECIMAL(3,1) CHECK ***(Height between 10.0 AND 20.0)***,
BirthDate DATE CHECK ***(BirthDate >='2015-01-01')***
);
On line 2 I added UNSIGNED, on line 4 I moved the comma, on line 5 I removed an extra check statement, my incorrectly formatted inequalities and rewrote it using between instead. I corrected the 6th line to use the proper date format.
As a result workbench was able to properly execute and added my table to the schema on the left side bar.
You said not to do this for you, so I'll just link you to relevant MySQL documentation and you can read them.
ID SMALLINT AUTO_INCREMENT PRIMARY KEY,
If you want it to be unsigned so it supports values 0 - 65535, you need to use SMALLINT UNSIGNED. See https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html
A signed SMALLINT can have values from -32768 to 32767. That is, the same total number of values (216), but half of them are negative.
CHECK (Breed="Egyptian Arab" "Holsteiner" "Quarter Horse" "Paint" "Saddlebred"),
If you want to compare to multiple values, use the IN(...) operator.
But I'd recommend using a lookup table instead of baking the list of horse breeds into your table definition. Using a lookup table is more flexible because you can add or remove values more easily, and each breed may need to have other attributes too.
Height DECIMAL(3,1) CHECK (Height=>10.0) CHECK (Height<=20.0),
MySQL supports an inequality operator >= but does not support a synonym operator =>. See documentation for operators: https://dev.mysql.com/doc/refman/8.0/en/comparison-operators.html#operator_greater-than-or-equal
In fact, I don't know any programming language that supports => or =< as inequality operators. They tend to support >= and <=. See https://en.wikipedia.org/wiki/Relational_operator#Standard_relational_operators
But even better for this case, use the BETWEEN operator. That way you don't need two inequality conditions.
BirthDate DATE CHECK (BirthDate=>"Jan 1, 2015")
Another use of => that should be >=.
MySQL doesn't understand that format for dates. You should use dates in YYYY-MM-DD format. See: https://dev.mysql.com/doc/refman/8.0/en/date-and-time-literals.html
Another option is to parse a string in the format you show into a MySQL-compatible date by using the STR_TO_DATE() function, but it's easier to just use the standard MySQL date format.
One more tip: You will thank yourself later if you learn the right types of quotes to use in SQL. See: When to use single quotes, double quotes, and backticks in MySQL
This is what I entered:
CREATE TABLE Horse (
ID SMALLINT UNSIGNED AUTO_INCREMENT,
RegisteredName VARCHAR(15) NOT NULL,
Breed VARCHAR(20) CHECK (Breed="Egyptian Arab" "Holsteiner" "Quarter Horse" "Paint" "Saddlebred"),
Height DECIMAL(3,1) CHECK (HEIGHT BETWEEN '10.1' AND '19.9'),
BirthDate DATE CHECK (birthdate > '2015-01-01'),
PRIMARY KEY (ID)
);

Indexing an array in a MySQL JSON column with variable length elements

I am trying to index json arrays where the contents are variable length strings and I can't figure out if its possible, let alone scalable.
A very similar question about indexing JSON data using the new multi value index is here: Indexing JSON column in MySQL 8
The syntax from that question executes, but using CHAR isn't right for me and ends in an error anyway. After changing names and adjusting the CHAR length for my data:
ALTER TABLE catalog ADD INDEX idx_30144( (CAST( j_data->>'$."30144"' AS char(250) ARRAY)) );
I get this error
1034 - Incorrect key file for table 'catalog'; try to repair it
Trying this:
ALTER TABLE catalog ADD INDEX idx_30144( (CAST( j_data->>'$."30144"' AS varchar(250) ARRAY)) );
Gives this error:
1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'varchar(250) ARRAY)) )' at line 1
This is an InnoDB table so obviously the 1034 error isn't accurate. It completes in around 2 seconds so while it could be running out of space, it happens too fast to see that, and there's 350 GB free on the drive.
I have over 200 JSON nodes like this that I would like to index, ideally. If this is a huge storage suck I can be happy with a subset of them, but I need to know if its possible in the first place.
You can only index such values, by generating a column which you index
Like
CREATE TABLE jempn (
id BIGINT(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
j_data JSON DEFAULT NULL,
g varchar(250) GENERATED ALWAYS AS (j_data->'$."30144"' ) STORED,
INDEX idx_30144 (g)
) ENGINE=INNODB;

MySQL processing large bit fields

My goal is to store a 256 bit object (this is actually a bitfield) into MySQL and be able to do some bitwise operations and comparisons to it.
Ideally, I would use BIT(256) for the type but MySQL limits bitfields to 64 bits.
My proposed solution was to use Binary String BINARY(32) type for this field and I can store my objects but there is no way I can operate on them.
My table structure is
CREATE TABLE `test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`bin` binary(32) NOT NULL,
PRIMARY KEY (`id`)
)
but then the query
SELECT
bit_count( bin ) AS fullBin,
bit_count( substring( bin, 0, 4 ) ) AS partialBin
FROM test
always returns 0 as it does not convert my binary string neither the substring into a number for bit_count to operate on.
I am looking for a way to extract parts of the binary string as BIGINT or some other type that I can operate on (I only need bitwise AND and bit_count() operations).
Performance wise, I would prefer a solution that does not involve creating strings and parsing them.
I would also accept any proposal for storing my data as another type but the obvious solution to split my bin column into 4 ones of type BIT(64) is not an option as I must preserve the table naming structure.

Mysql returns Long from PreparedStatement.getGeneratedKeys();

Using JDBC 3 driver, one can insert a record into a table and immediately get autogenerated value for a column. This technique is used in ActiveJDBC.
Here is the table definition:
CREATE TABLE users (id int(11) NOT NULL auto_increment PRIMARY KEY, first_name VARCHAR(56), last_name VARCHAR(56), email VARCHAR(56)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
This is working fine on H2 and PostgreSQL, and the type of the returned value is Integer.
However, in MySQL the type is Long, while I believe it should be Integer.
When querying this same row in Mysql, the "id" comes back as Integer.
Anyone knows why the "getGeneratedKeys()" returns java.lang.Long in Mysql and how to fix it?
The why:
The generator that MySQL uses for keeping track of the value is BIGINT, so the driver describes it as BIGINT, and that is equivalent to Long. See LAST_INSERT_ID in the MySQL manual.
Drivers like PostgreSQL return the actual column of the table (actually PostgreSQL returns all columns when using getGeneratedKeys(); I assume that MySQL simply calls LAST_INSERT_ID().
How to solve it:
As indicated by Jim Garrison in the comments: Always use getInt(), or getLong(), and not getObject().

What kind of integer should I use in MySQL?

I'm creating the database schema for a system and I started to wonder something about the Integer datatypes in MySQL. I've seen that, at least in Moodle, the datatypes are sometimes TINYINT (for stuff like flags), INT (for id numbers) or BIGINT (for almost-infinite AI values, like user id's).
I was wondering: how does that affect the actual database? If I use INT for something like a flag (e.g 1 = pending, 2 = in process, 3 = revewing, 4 = processed) instead of TINYINT or BIGINT, does it has repercussions? What about not setting up constraints? (Like, again, with a flag, using TINYINT(1) or TINYINT without an specific number)
The size that you provide will not affect how data is stored.
So INT(11) is stored on disk the same way as INT(3).
With your example of
1 = pending, 2 = in process, 3 = revewing, 4 = processed
I would use an ENUM('pending', 'inprocess', 'revewing', 'processed') instead. That keeps it readable in your code and in the data, while it provides the same speed as using an integer.
What is the difference between tinyint, smallint, mediumint, bigint and int in MySQL?
You should read about the different numeric datatypes and make your decision based on that.