external GUID to satisfy unique constraint in mysql - mysql

I have a MYSQL 8.x table, each row is unique since the PK is auto incremented. A column transactionID is used to store an external transactionID that needs to be coupled with the row/record.
However a new requirement came and we want to create a new row with the same transactionID. I was thinking to add a new column that holds the GUID of the transaction.
Is this good idea? Is this going to be slow? Are there any second thougths regarding uuid as strings? MySQL 8.0 added UUID_TO_BIN and BIN_TO_UUID function that could store UUID as number.
CREATE TABLE `testme`.`new_table` (
`ID` INT NOT NULL AUTO_INCREMENT,
`transactionID` INT NOT NULL,
`maybe_uuid` VARCHAR(45) NOT NULL,
PRIMARY KEY (`ID`));
ALTER TABLE `testme`.`new_table`
ADD UNIQUE INDEX `index2` (`transactionID` ASC, `maybe_uuid` ASC) VISIBLE;
;

GUIDs are not great for use as a primary key for many reasons that i will not detail here and it would faster to use you auto_increment key that is already in place. But if you also need to store the GUID it is perfectly reasonable to just add another column for that. And you can use the two functions you mentioned.

Related

Why are there are two rows in MariaDB database violating unique constraint?

I have written an application in Javascript which inserts data into two tables via a connection to a MariaDB server.
There should be a 1:1 correspondance between the rows in these tables when first running the application.
One table stores (simulated) data about properties, the other table stores data about prices. There should be 1 price for each property. At a later date, the price might change, so there could be more than one entry for the price, but this cannot happen when the application is first run. These entries also cannot be in violation of a unique index - but they are.
Perhaps I have misconfigured something in MariaDB? Here is the code which generates the tables.
drop table if exists property_price;
drop table if exists property;
create table property
(
unique_id bigint unsigned not null auto_increment primary key,
web_id bigint unsigned not null,
url varchar(256),
street_address varchar(256),
address_country varchar(64),
property_type varchar(64),
num_bedrooms int,
num_bathrooms int,
created_datetime datetime not null,
modified_datetime datetime not null
);
create table property_price
(
property_unique_id bigint unsigned not null,
price_value decimal(19,2) not null,
price_currency varchar(64) not null,
price_qualifier varchar(64),
added_reduced_ind varchar(64),
added_reduced_date date,
created_datetime datetime not null
);
alter table property_price
add constraint fk_property_unique_id foreign key(property_unique_id)
references property(unique_id);
alter table property
add constraint ui_property_web_id
unique (web_id);
alter table property
add constraint ui_url
unique (url);
alter table property_price
add constraint ui_property_price
unique (property_unique_id, price_value, price_currency, price_qualifier, added_reduced_ind, added_reduced_date);
Below is a screenshot from DBeaver showing that a select statement returns two identical rows.
I don't understand why the unique constraint appears to be violated. The constraint does sometimes work, because if I run my application again, it fails because it attempts to insert a duplicate row which already exists in the DB. (Not the same as the one shown below.)
Can anyone point me in the right direction as to how I might debug this?
MariaDB permits multiple values on columns which form part of a unique constraint.
My solution would be to put the logic for checking for duplicate rows into the application, rather than this being on the database side. Essentially this means the unique constraint is not being used.

How can we migrate sequence in PostgreSQL to Mysql

All,
I am trying to migrate from PostgreSQL DB to MySql DB. I have used sequence in some table to get auto increment column other than the primary key. How to create auto increment column which is the primary key in Mysql DB.
I am listing an example table below in PostgreSQL.
CREATE TABLE bills
(
id serial NOT NULL,
billname character varying(255) NOT NULL,
invoiceid character varying(255) NOT NULL DEFAULT nextval('bill_invoiceid_seq'::regclass),
CONSTRAINT combine_campaigns_pkey PRIMARY KEY (id)
)
In the example, "id" is the primary key and invoice id is not a key but getting auto increment
MySQL int auto_increment primary key should be very similar to postgreSQL serial (which does not need to be a primary key)
If you want to reserve some used sequence, you can insert a value (eg 3000) into MySQL auto_increment field, after that any new record will increase from this value i.e. 3001 onwards:
The equivalent for a SERIAL column in mysql is AUTO_INCREMENT. Define your primary key as follows:
CREATE TABLE my_table(
id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
...
)
or
CREATE TABLE my_table(
id int NOT NULL AUTO_INCREMENT ,
...
PRIMARY KEY(id)
)
Be aware that in mysql you can only have one AUTO_INCREMENT per table. Also worth mentioning is that you are moving from an RDBS that is rich in features and closer to standard compliance to one that has less features and less compliant.

What is the default primary key generation strategy for MySQL

I have been using AUTO_INCREMENT attribute to generate a primary key when a new row is inserted into a table in MySQL.
Could somebody help me understand what is the default primary key generation strategy for MySQL and how does it work?
EDIT
Hibernate has a identifier generation strategy native selects identity, sequence or hilo depending upon the capabilities of the underlying database. I used MySQL with hibernate.hbm2ddl.auto=update which generated id BIGINT(20) NOT NULL AUTO_INCREMENT for id property of Long Java data type.
I am trying to understand how did Hibernate choose AUTO_INCREMENT when it used SchemaExport tool. Is AUTO_INCREMENT the default primary key generation strategy for MySQL?
From here
The AUTO_INCREMENT attribute can be used to generate a unique identity for new rows.
If no value was specified for the AUTO_INCREMENT column, so MySQL assigned sequence numbers automatically. You can also explicitly assign 0 to the column to generate sequence numbers. If the column is declared NOT NULL, it is also possible to assign NULL to the column to generate sequence numbers.
The value will be incremented for each new row
The value is unique, duplicates are not possible
If a row is deleted, the auto_increment column of that row will not be re-assigned.
The auto_increment value of the last inserted row can be accessed using the mySQL function LAST_INSERT_ID() but it must be called right after the insert query, in the same database connection
Always not necessary to use auto increment to put it as primary key.
CREATE TABLE Persons
(
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
PRIMARY KEY (P_Id)
)
You can use 'SERIAL' data type.
CREATE TABLE test(
"id" Serial NOT NULL,
);
ALTER TABLE "test" ADD CONSTRAINT "Key1" PRIMARY KEY ("id");

PRIMARY KEY definition in MySQL CREATE TABLE statement

What's the difference between this code:
CREATE TABLE samples (
sampleid INT(11) NOT NULL AUTO_INCREMENT,
sampledate DATE NOT NULL,
location VARCHAR(25) NOT NULL,
PRIMARY KEY (sampleid)
)
ENGINE=InnoDB;
and this:
CREATE TABLE samples (
sampleid INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
sampledate DATE NOT NULL,
location VARCHAR(25) NOT NULL,
)
ENGINE=InnoDB;
code?
So a separate PRIMARY KEY statement or as part of a column definition. Same question for UNIQUE INDEX and UNIQUE keyword in column definition.
The second syntax is merely a shortcut allowing you to specify the column and add an index on it in a single clause.
This works out fine in cases where you simply want to create a column and add an index on it.
You'll need to use the first syntax if you want to do something more complicated, such as adding an index based on multiple columns rather than a single column, or if you are adding or changing an index on an existing column; that is, you are not creating the column and the index on it at the same time.
MySQL allows uses the PRIMARY KEY directive to allow you to set the Primary Key dynamically. Supplying PRIMARY KEY as an argument to the constructor can only be called on creating the column. PRIMARY KEY(X), PRIMARY KEY(Y), PRIMARY KEY(Z) allows for changing the primary keys on subsequent queries.
The way I see it is.. The first method is used to create composite keys. While the second method (more readable to me) is primarily used if there is only primary key in the table.
The second method cannot be used if you want to implement composite key
There are many ways to skin a cat and above 2 examples are just 2 of them. They are identical. There's no difference.
They are literally the same. Here is a quick site that shows you the different ways (3) to do it. http://www.java2s.com/Code/SQL/Key/Defineanduseprimarykey.htm

What willl be the fast method for a domain store in MySQL?

I want to store domain names(example:google.com - without "http://" and "www")in MySQL as primary key+Index.
so when I call a domain through PHP I should get the result according to that domain faster.
Right now I am inserting domain in plain text.
is it right way to do it?? or do I need to hash it??
your Ideas please
I think you should not use char/varchar in primary index. Rather create an int PK and domain column with unique constraint.
I think that would work in your case.
Checkout some reasons here:
CHAR() or VARCHAR() as primary key in an ISAM mySQL table?
http://forums.mysql.com/read.php?153,243809,243818#msg-243818
EDIT
Here is the sample table. I created this table on assumptions. Change it according to your need.
CREATE TABLE IF NOT EXISTS `test`.`sample` (
`id` INT NOT NULL AUTO_INCREMENT ,
`domains` VARCHAR(100) NOT NULL ,
PRIMARY KEY (`id`) ,
UNIQUE INDEX `domains_UNIQUE` (`domains` ASC) );
P.S. Created using mysql workbench.