Migrating Varchar to Text in Mysql - mysql

I am converting one of the "Varchar" column in mysql table to a text field. I am simply using single alter command to convert the type. When i read about text and varchar came to know that it had difference in storing mechanisms.
Am I supposed to write any migration script to change the type of column and move data or a single type altering command is enough ?

ALTER TABLE table_name MODIFY column_name TEXT NOT NULL;

There is no a big problem to change varchar to text because text supports more data length than varchar, but if the field has a index it must be drop and create new index with prefix col_name(length) (see CREATE INDEX syntax).
According to your data content maybe would be a good idea use fulltext indexes but that implies change your search expressions on that field.
If you are in production environment, the table will be locked meanwhile the migration is in progress to prevent data loss.

Related

Error when adding column with numeric name

I currently have a MariaDB database with columns named after dates : 20200105, 20200914 etc.
If I try to add a column using ALTER TABLE dates ADD COLUMN IF NOT EXISTS (test VARCHAR(255));, it works and the test column is created.
If I type ALTER TABLE dates ADD COLUMN IF NOT EXISTS (20201205 VARCHAR(255));, though (so, with a number replacing "test"), the creation does not work anymore and MariaDB tells me that there is an error with my SQL syntax.
I have tried to put quotes around the column name, but that does not work (not even with "test").
Is there something obvious I am missing ?
Use backticks to escape the column name:
ALTER TABLE dates ADD COLUMN IF NOT EXISTS (`20201205` VARCHAR(255));
But really best practice frowns upon the use of naming your database objects with mandatory backticks. The reason for using a name like 20201205 as a column name is that you will forever be needing to escape it using backticks. Also, from a data design point of view, your data should grow with new dates in terms of increasing the number of records, not columns.

Change MySQL numerical field to char using a function

I have a table in MySQL DB with a field for storing IP address. It stores it as a number (int). I'd like to change the structure to use string (char) instead.
Is it possible with single ALTER TABLE statement? As far as I can see in Postgres it is possible to specify a conversion function to ALTER TABLE, but I don't see an equivalent for MySQL.
A workaround is of course to:
alter table by adding a new char() field
update that new field from the old one using inet_ntoa
alter table by removing old field
and finally renaming new field to the same name as the old one had
But maybe there is a simpler solution?
You can simply alter the column to varchar. mysql will automatically convert the values. I can confirm this with mysql 5.6.
but before you do this, you should definetely create a backup and maybe try this with a small test table.

How do I change the data type for all columns in MySQL?

I want to change the datatype for all columns in my table mysql.
For instance varchar to double.
alter table myTable alter column vColumn int;
This will work as long as:
-all of the data will fit inside an int
-all of the data can be converted to int (i.e. a value of "car" will fail)
-there are no indexes that include vColumn. If there are indexes, you will need to include a drop and create for them to get back to where you were.
Changing of column types is possible with SQL command ALTER TABLE MODIFY COLUMN (it does not work in every DBMS, however).
Usually you have to remove data anyway, so another option would be to DROP TABLE (=remove it entirely) and create anew with desired columns (with CREATE TABLE). You could also remove just the single column (ALTER TABLE DROP COLUMN) and add a new one (ALTER TABLE NEW COLUMN) with the new definition.
Of course changing a column is so simple only as long as this column is not used in any constraints or keys
For syntax of the above commands see MySQL docs

What does MySQL converting varchar to char?

When we add a new table, we made a mistake : a field was a varchar(255), but we have to write join queries.
So we alter table to make a char(6).
My question is : what does MySQL in this case ?
It trims right ?
Rather than worry about what MySQL does or doesn't do why not just convert the data yourself before the change.
e.g.
UPDATE YourTable
SET YourField = LEFT(YourField,6);
ALTER TABLE YourTable MODIFY COLUMN YourField Char(6)
You should note that if your column data is too long it won't let you do the alter assuming enable strict SQL mode see Shef's complete answer
It will try to convert the format. In your case, the column is a string type, so it will truncate the value, if the strict SQL mode is not enabled.
When you change a data type using CHANGE or MODIFY, MySQL tries to
convert existing column values to the new type as well as possible.
Warning This conversion may result in alteration of data. For example,
if you shorten a string column, values may be truncated. To prevent
the operation from succeeding if conversions to the new data type
would result in loss of data, enable strict SQL mode before using
ALTER TABLE (see Section 5.1.6, “Server SQL Modes”).
Read the fine warning down two fifth of the page.
MySQL won't even let you alter the table if there's any case you'll lose data (e.g. a row has an entry where the field's text is longer than six characters), so you're better off converting the data how you see fit.

Applying an Index to a Blob/Longtext field

I am trying to create an index on a particular text string using Hibernate annotations. What I am currently doing is:
#Index(name="guid_index")
#Column(length=1400)
private String myGUID;
However, since the length of the column is 1400, this maps to SQL using the longtext type. hbm2ddl is able to create the table without mishap, but when it tries to create the index, I get:
Unsuccessful: create index guid_index on table_name (myguid);
BLOB/TEXT column 'myguid' used in key specification without a key length
How can I create an index on this column using Hibernate?
I initially thought that HHH-4389 was what you're looking for but your case seems to be a different issue: Hibernate is simply not generating the expected DDL statement. I would open a new Jira issue.
You have to specify a length of index.
Maximum length depends on storage engine, but usually it's not more than 1000 bytes,
if charset is utf-8, you have to divide maximum lengh by 3.
create index guid_index on table_name (myguid (1000) );
It's good enough for WHERE field LIKE 'prefix%' and WHERE field = 'text' conditions.