How to define prefix index as primary key in liquibase? - spring

I have a table in which the primary key value can be long.
When I try to redefine the primary column length, I get the following error
liquibase.exception.DatabaseException: Specified key was too long; max key length is 3072 bytes
I'm guessing the above error is due to MySQL's default max index size, so it seems like my next best option atm is to define this primary key with a prefix index (or maybe expand the max index length here somehow).
Is there any way to do that with liquibase?

I don't know how to get Liquibase to define a primary key with an index prefix, but it won't help to use an index prefix anyway.
https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html says:
The object key name is a sequence of Unicode characters with UTF-8 encoding of up to 1,024 bytes long.
Thus it's between 255 and 1024 characters, depending on how many of the characters are multibyte.
But MySQL index prefix syntax measures length in characters, not bytes.
So you would need to define an index prefix length of 1024 to handle S3 keys, but that's too long for a MySQL index definition.
You must define a different column as the primary key in this table. For example, you could use an MD5() hash of the S3 object key name, and store that in a CHAR(32) or BINARY(16).

Related

How unique index internally works in Oracle?

I have read some articles and oracle documentation on unique and nonunique indexes. What I understood is Index is Index and constraint is constraint.
Constraint uses the index to ensure data integrity.
The primary key uses the unique or nonunique index to ensure that column is unique and not null.
The same goes for unique constrain.
But constraints can use a non-unique index if we want them deferrable.
The question comes for a unique index, it is just an index and I can not see any constraint associated with it so what is going on internally so the unique index won't allow for duplicate values, it is some internal semantics working as a constraint to ensure index uniqueness?
And let's say a unique index has the ability to be unique without any constraint then I want to understand the relation of constraints with indexes in every sense.
"There really is no such thing as a nonunique entry in a B*Tree index. In a nonunique index, Oracle simply stores the rowid by appending it to the key as an extra column with a length byte to make the key unique. For example, an index such as CREATE INDEX I ON T(X,Y) is conceptually CREATE UNIQUE INDEX I ON T(X,Y,ROWID). In a unique index, as defined by you, Oracle does not add the rowid to the index key. In a nonunique index, you will find that the data is sorted first by index key values (in the order of the index key) and then by rowid ascending. In a unique index, the data is sorted only by the index key values".
Though unique, primary key constraints and unique indexes both help with uniqueness, their objectives differ.
A unique or primary key constraints are meant to enforce data integrity. They might create a unique index implicitly and then it uses unique index to maintain integrity or it can use nonunique index as the key enforcement. Anyway index (unique or nonunique) always used to support primary key.
A unique index serves to make data access efficient. Its primary purpose is to help performance, but it does maintain uniqueness as a corollary and primary key may use this.

Suitable Primary key type in oracle

What is the difference if we make primary key as
varchar2
byte[] <-18
How it will impact the searching in a table.
If you mean what is the difference between varchar2(18 char) or varchar2(18 byte), it won't mean anything from the perspective of the primary key.
If you define the field as VARCHAR2(18 BYTE), Oracle can use up to 18 bytes for storage, but you may not actually be able to store 18 characters in the field, because some of them take more than one byte to store, e.g. non-English characters, ascii extended characters.
In the primary key, an automatic unique index is associated to it. So, with a character set as UTF-8, an index might occupy more space when using char than byte. But, normally speaking, it will have no relation whatsoever with either using char or byte.
Keep in mind that if you use multibyte charactersets as UTF-8, then the space consumed by the data types will be greater when you use CHAR instead of BYTE as NLS_SEMANTICS.
So, the greater the storage, the bigger the index, then more time/cpu consuming when you access to it.
Hope it helps.
Regards

Do I need a primary key with an Oracle identity column?

I am using Oracle 12c and I have an IDENTITY column set as GENERATED ALWAYS.
CREATE TABLE Customers
(
id NUMBER GENERATED ALWAYS AS IDENTITY,
customerName VARCHAR2(30) NULL,
CONSTRAINT "CUSTOMER_ID_PK" PRIMARY KEY ("ID")
);
Since the ID is automatically from a sequence it will be always unique.
Do I need a PK on the ID column, and if yes, will it impact the performance?
Would an index produce the same result with a better performance on INSERT?
No, you don't need a primary key necessarily, but you should always provide the optimiser as much information about your data as possible - including a unique constraint whenever possible.
In the case of a surrogate key (like your ID), it's almost always appropriate to declare it as a Primary Key, since it's the most likely candidate for referential constraints.
You could use an ordinary index on ID, and performance of lookups will be comparable depending on data volume - but there is virtually no good reason in this case to use a non-unique index instead of a unique index - and there is no good reason in this case to avoid the constraint which will require an index anyway.
Yes, you always should have a Uniqueness constraint (with rare exceptions) on an ID column if indeed it is (and should be) unique, regardless of the method by which it is populated - whether the value is provided by your application code or via an IDENTITY column.

Should I index primary key column(s) in Oracle

I've recently stopped to think that Primary Keys are not indexes, they're a combination of Unique and Null constraints. And till now, I've never created index for PK columns. My question is if I should create index for PK columns if this column is going to be used in the WHERE part of many queries.
Oracle will create an index for you, or can use an existing one. Whether a unique or non-unique index is used is up to you.
http://docs.oracle.com/cd/B28359_01/server.111/b28310/indexes003.htm#i1006566
A primary key itself is not an index, and nor is a unique constraint -- they are both constraints. However an index is used to support them.
A unique index is rather different as it can exist in the absence of a unique or primary key constraint, and neither constraint type require that the index supporting it be unique.

Is it ok to define multiple NCLOB columns in an oracle table?

I've got to store multiple text fields of variable length in an oracle database. I'd need to define them as columns of the same table to be able to order the results when I query it.
I can't know the max size of the field contents, most of them will be less than 100 characters but there could be some of thousands of chars. Furthermore the number of fields changes dinamically.
I was thinking of defining a table with multiple NCLOB columns that would allow me to store anything in them (very short and very long texts) But I wonder if this would be the right design.
Summary:
Variable number of fields (metadata of the same object)
Variable length of the content
I need to order the results
Thanks
KL
When you need variable number of fields, it's better to split the table into parent and child. Then you can effectively have any number of fields. And you can add order column to store ordering information to order the result. You can query by joining the two table and use order by clause to order the result. Also you can add foreign key constraint to make sure the relationship and data integrity.
In the case of variable length of contents, you can use varchar2(or nvarchar2) to store text date. Varchar2 can hold characters up to 4000 bytes. If you know that the maximum length of the content can be longer than 4000 bytes, you should use CLOB(or NCLOB).

Resources