MySQL: Get Row Size by Column - mysql

I tried to alter one column in an existing table, from Varchar(5000) to Varchar(10000) using SQLyog.
This resulted in an error:
Row size too large. The maximum row size for the used table type, not
counting BLOBs, is 65535. This includes storage overhead, check the
manual. You have to change some columns to TEXT or BLOBs.
I understand from this forum that I need to change this large Varchar field to Text - which I assume is stored 'outside' of the table in Innodb - but I would be interested in seeing a list of all columns for the table and the size they use.
Can anyone suggest a query etc, that could do this?

Look into information_schema.COLUMNS table, it has lot of such details.
This is query for getting varchar columns and their length for any table-
SELECT COLUMN_NAME, CHARACTER_MAXIMUM_LENGTH
FROM information_schema.COLUMNS AS ins
WHERE ins.TABLE_NAME = '<your table name>' AND ins.DATA_TYPE = 'varchar'

To see a list of all columns for the table and the size they use, you can run:
describe my_table;
Or to see the create table statement:
show create table my_table;

Related

Increase every varchar field length by factor of 5

I failed to account for something in my data, and I would like to MySQL increase every varchar field length in one table by factor of 5. Is there an easy way to do this?
"Easy" depend on how many tables and columns you have to modify, but you could select the relevant table_name, column_name, and character_maximum_length values from information_schema.columns into a new table, multiply the length values by 5, and concatenate the values into ALTER TABLE statements. Then you will need to execute that set of generated statements.
If there are primary and foreign keys using these columns, you will have to drop them first and recreate them afterward.

Replace column names, table names and other structures using a query

I want to search the structure of my MySQL db and replace structures that contain or equal "xyz*"... column names and table names are the main thing, but I'd like to search all structures.
Then, I want to replace "xyz*" with "abcdefg".
I doubt one can do this with one query. What you can do is create ALTER statements. I would write a small program (in the language of your choice) and
first I would get the table names like this:
select table_name from information_schema.tables;
The result set has to be checked in a loop, if there is a table named "xyz*" then create an ALTER statement:
RENAME TABLE tbl_name TO new_tbl_name
For the colums, you would have to get each Table again, then all colums for each table:
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'tbl_name';
the again a loop to change the columns name, this time using ALTER TABLE.
see also:
https://dev.mysql.com/doc/refman/5.1/en/alter-table.html
https://dev.mysql.com/doc/refman/5.0/en/rename-table.html

How can I modify an existing column's data type?

One of the columns in a somewhat large table (~10,000 records) is of the data type DECIMAL(10,0). I'm using MySQL.
I'd like the values to be displayed to 2 decimal places, so I need to alter this to DECIMAL(10,2), without screwing up the table's existing records. How could this be done?
Which DBMS are you using ? you can try like this for MySQL :
alter table tblName modify columnName newDataType;

When you alter a table how do you detect the data type of columns?

I am running MySQL and I need to change the data type of certain columns from an enumeration to integer. However, there are a lot of columns. (If this exists) What is the syntax to alter all columns at the same time that are enumerations. Here is how I am updating a single column to make it integer data type:
ALTER TABLE table_name CHANGE column_name column_name INTEGER;
SHOW COLUMNS FROM WHERE TYPE LIKE "%enum%"
you could afterwards iterate through your result similar to the solution described here:
http://se2.php.net/manual/en/function.mysql-fetch-field.php#92069
hope this helps,
Michael

Equivalent of varchar(max) in MySQL?

What is the equivalent of varchar(max) in MySQL?
The max length of a varchar is subject to the max row size in MySQL, which is 64KB (not counting BLOBs):
VARCHAR(65535)
However, note that the limit is lower if you use a multi-byte character set:
VARCHAR(21844) CHARACTER SET utf8
Here are some examples:
The maximum row size is 65535, but a varchar also includes a byte or two to encode the length of a given string. So you actually can't declare a varchar of the maximum row size, even if it's the only column in the table.
mysql> CREATE TABLE foo ( v VARCHAR(65534) );
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs
But if we try decreasing lengths, we find the greatest length that works:
mysql> CREATE TABLE foo ( v VARCHAR(65532) );
Query OK, 0 rows affected (0.01 sec)
Now if we try to use a multibyte charset at the table level, we find that it counts each character as multiple bytes. UTF8 strings don't necessarily use multiple bytes per string, but MySQL can't assume you'll restrict all your future inserts to single-byte characters.
mysql> CREATE TABLE foo ( v VARCHAR(65532) ) CHARSET=utf8;
ERROR 1074 (42000): Column length too big for column 'v' (max = 21845); use BLOB or TEXT instead
In spite of what the last error told us, InnoDB still doesn't like a length of 21845.
mysql> CREATE TABLE foo ( v VARCHAR(21845) ) CHARSET=utf8;
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs
This makes perfect sense, if you calculate that 21845*3 = 65535, which wouldn't have worked anyway. Whereas 21844*3 = 65532, which does work.
mysql> CREATE TABLE foo ( v VARCHAR(21844) ) CHARSET=utf8;
Query OK, 0 rows affected (0.32 sec)
TLDR; MySql does not have an equivalent concept of varchar(max), this is a MS SQL Server feature.
What is VARCHAR(max)?
varchar(max) is a feature of Microsoft SQL Server.
The amount of data that a column could store in Microsoft SQL server versions prior to version 2005 was limited to 8KB. In order to store more than 8KB you would have to use TEXT, NTEXT, or BLOB columns types, these column types stored their data as a collection of 8K pages separate from the table data pages; they supported storing up to 2GB per row.
The big caveat to these column types was that they usually required special functions and statements to access and modify the data (e.g. READTEXT, WRITETEXT, and UPDATETEXT)
In SQL Server 2005, varchar(max) was introduced to unify the data and queries used to retrieve and modify data in large columns. The data for varchar(max) columns is stored inline with the table data pages.
As the data in the MAX column fills an 8KB data page an overflow page is allocated and the previous page points to it forming a linked list. Unlike TEXT, NTEXT, and BLOB the varchar(max) column type supports all the same query semantics as other column types.
So varchar(MAX) really means varchar(AS_MUCH_AS_I_WANT_TO_STUFF_IN_HERE_JUST_KEEP_GROWING) and not varchar(MAX_SIZE_OF_A_COLUMN).
MySql does not have an equivalent idiom.
In order to get the same amount of storage as a varchar(max) in MySql you would still need to resort to a BLOB column type. This article discusses a very effective method of storing large amounts of data in MySql efficiently.
The max length of a varchar is
65535
divided by the max byte length of a character in the character set the column is set to (e.g. utf8=3 bytes, ucs2=2, latin1=1).
minus 2 bytes to store the length
minus the length of all the other columns
minus 1 byte for every 8 columns that are nullable. If your column is null/not null this gets stored as one bit in a byte/bytes called the null mask, 1 bit per column that is nullable.
For Sql Server
alter table prg_ar_report_colors add Text_Color_Code VARCHAR(max);
For MySql
alter table prg_ar_report_colors add Text_Color_Code longtext;
For Oracle
alter table prg_ar_report_colors add Text_Color_Code CLOB;
Mysql Converting column from VARCHAR to TEXT when under limit size!!!
mysql> CREATE TABLE varchars1(ch3 varchar(6),ch1 varchar(3),ch varchar(4000000))
;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> SHOW WARNINGS;
+-------+------+---------------------------------------------+
| Level | Code | Message |
+-------+------+---------------------------------------------+
| Note | 1246 | Converting column 'ch' from VARCHAR to TEXT |
+-------+------+---------------------------------------------+
1 row in set (0.00 sec)
mysql>