How can I generate a uuid/guid in MariaDB 10.1? - mariadb

I have a BINARY(16) column since MariaDB 10.1 doesn't support GUID fields yet. I was hoping to use mysql's random_bytes(16) function to generate some guid's in a query (or even as a default value?). Unfortunately this is not available in mariadb so I'm looking for an alternative that isn't terrible.

There is a article on GUIDs in MariaDB knowledge base, and a stored function that would generate a BINARY(16) sequential UUID. To generate a 36-byte UUID as string, use UUID() function.

Related

Why uuid() creates very similar identifiers in MariaDB?

I am creating a code generator for MariaDB to create a database based on a given JSON.
In that JSON, some initial data also exists. Thus I loop over data and insert them into the database.
Some columns have uuid() default value.
Here's the result of my code inserting data into such a table:
Id,Guid,Key,Order
1,5c52e1db-6809-11ec-982c-0242c0a81003,New,
2,5c530e55-6809-11ec-982c-0242c0a81003,WaitingForBusinessResponse,
3,5c533551-6809-11ec-982c-0242c0a81003,WaitingForUserResponse,
4,5c536433-6809-11ec-982c-0242c0a81003,UnderInvestigation,
5,5c538ba5-6809-11ec-982c-0242c0a81003,Closed,
As you can see UUID values are very very close to each other. This column has a unique index on it, so no duplicate entries would be allowed. But these values make it difficult to track them and one might easily confuse them with each other.
Is there a way to change this behavior? I want to tell MariaDB to create UUID more randomly.
The simple answer is "no, you can't" unless you write your own uuid function which provides an algorithm which creates a uuid() from random or pseudo random number as described in Chapter 4.4 of RFC 4122
The uuid() function of MariaDB (and MySQL) was implemented according to RFC 4122, but uses the algorithm for creating a time based uuid (see chapter 4.2)
Since all algorithms (name based, time based, random) deliver an Universal Unique Identifier which is globally unique in space and time, I don't really understand why you want to change the algorithm from time to random.
Time based uuids using uuidgen and mariadb:
~$ uuidgen -t;uuidgen -t
a5d3c032-6865-11ec-bd1f-1740cb8be951
a5d42d24-6865-11ec-bd1f-1740cb8be951
~$ mariadb -e"select uuid()\G";mariadb -e"select uuid()\G"
*************************** 1. row ***************************
uuid(): 45aca397-683c-11ec-a913-d83bbf89f2e2
*************************** 1. row ***************************
uuid(): 45ad94dd-683c-11ec-a913-d83bbf89f2e2

OpenEdge SQL Field Width on system tables

I need to alter the SQL Field Width for columns on the system tables _aud-audit-data and _aud-audit-data-value.
Is this possible from within the Data Dictionary interface?
Or is there an alternative non-4GL way of doing this?
Prior to 11.6 using dbtool is the standard way to adjust SQL width. It is fast, safe and effective:
http://knowledgebase.progress.com/articles/Article/P24496
You can also use the data dictionary or SQL code to update the SQL width field in the meta schema directly but that is not recommended.
Starting from OpenEdge version 11.6 a new database startup parameter was introduced:
-SQLWidthUpdate ON
that can automatically fix the SQL width of character datatypes (not for numerical datatypes).
More information about this new feature can be found here:
https://community.progress.com/community_groups/openedge_rdbms/f/18/t/19534
There are lots of information about this in the Knowledgebase.
You can do it by SQL:
http://knowledgebase.progress.com/articles/Article/P128368
There's a utility called "dbtool" that perhaps you can use.
http://knowledgebase.progress.com/articles/Article/P24496
Note: you might have to prefix the tables with PUB ie:
ALTER TABLE PUB.<table name>
ALTER COLUMN <column name>
SET PRO_SQL_WIDTH <value>;
(Code taken from the link above, not tested).

Oracle DB vs Mariadb

I have to find out in MariaDb how to implement some features used in Oracle . I have :
Load a file: in Oracle I use the external table. Is there a way (fast and efficient one ) to load a file into a table . Has MariaDb a plugin which allows to load well a specific format of files?
In my existing Oracle code I used to developp a java wrap functions which allow those feature (is there a way in MariaDb to do this?), specifically :
1- Searching a files in an OS directory and insert them in a table,
2- send an SNMP trap
3- Send a mail via SMTP
Is there an equivalent to an Oracle job in Mariadb?
Is there an equivalent to Oracle TDE (Transparent data encryption) ?
Is there an equivalent to the VPD (virtual private policy)?
What is the maximum length of a varchar column/variable ? (in Oracle we can use the CLOBs..)
Many Thanks and Best Regards
MariaDB (and MySQL) can do a LOAD DATA on a CSV file. It is probably the most efficient way to convert external data to a table. (There is also ENGINE=CSV, which requires no conversion, but is limited in that it has no indexes, etc.)
MariaDB cannot, for security reasons, issue any arbitrary system calls. No emails, no 'exec', etc.
No Job, TDE, VPD.
Network transmissions can (optionally) use SSL for encryption at that level.
There is a family of virtually identical datatypes for characters:
CHAR(n), VARCHAR(n) -- where n is up to 65535; n is the limit of _characters_, not _bytes_.
TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXT -- of various limits; the last is limited to 4GB.
For non-character storage (eg, images), there is a similar set of datatypes
BINARY(n), VARBINARY(n)
TINYBLOB, BLOB, MEDIUMBLOB, LONGBLOB
The various sizes of TEXT and BLOB indicate whether that is a 1-, 2-, 3-, or 4-byte length field in the implementation.
NVARCHAR is a synonym for VARCHAR. Character sets are handled by declaring a column to be, for example, CHARACTER SET utf8 COLLATE utf8_unicode_ci. Such can be defaulted at the database (schema) level, defaulted at the table level, or specified differently for different columns (even in the same table).

Is flyway database agnostic in its support for multiple databases?

Is Flyway suitable for implementation in an application that will support multiple databases?
We don't know what our customers are using - could be either MySQL, Postgres or Oracle. Can we still use Flyway to migrate the database for new versions of the application?
if your question is: does Flyway provide a DDL abstraction layer across the databases it supports, the answer is no.
This was a conscious design decision, to make sure the full power of the underlying database is available and not just the smallest common denominator supported by the migration tool.
For your use case, you could either provide different migration scripts for the different databases. They should be very similar though.
If you do not wish to potentially duplicate the migration scripts and can live with the smallest common denominator approach, have a look at LiquiBase which might be a better fit for your usecase (if you can live with the XML)
You could use jOOQ's parsing connection, which wraps your target JDBC connection and is capable of translating your input DDL to any target dialect (if it's not too fancy and vendor specific). Flyway wouldn't be aware of this translating JDBC proxy, and wouldn't have to be. The online version of the SQL translator can be seen here. For example, if your input SQL is a MySQL specific:
create table t (i int primary key auto_increment);
The output could be:
-- Oracle
create table T (
I number(10) generated by default as identity(start with 1) not null,
primary key (I)
);
-- SQL Server
create table T (
I int identity(1, 1) not null,
primary key (I)
)
-- PostgreSQL
create table T (
I int generated by default as identity not null,
primary key (I)
)
-- PostgreSQL 9.4
create table T (
I serial4 not null,
primary key (I)
)
Disclaimer: I work for the company behind jOOQ.

SQLIite - how to add special data?

I is there a way to add "additional info" to a sqlite database. Something like date of creation of a database, amount of entries or name of user who created it. If I don't want to create special tables in order to store all this info especially if there will only be one of each type.
Thank you in advance.
Why not use one special table and store each special value as a name-value pair?
CREATE TABLE SpecialInfoKeyValues (
Key VARCHAR UNIQUE COLLATE NOCASE,
Value
);
Since SQLite uses "manifest typing," you can store any kind of value you want in there.
In short, no. SQLite has no concept of users, and doesn't store creation metadata.
No, there is no way to do that, you will have to use a "special" table to carry data within the file, or you will have to use external means.
There are, however, two version counters stored within the database itself: the schema_version and the user_version (see Pragmas to query/modify version values for details.) Perhaps you could abuse those. Please keep in mind, though, that by default the sqlite3 shell application does not store those when you use the .dump command to dump the database into a textual representation.

Resources