Una tarea bastante común de revisión en una base de datos es encontrar el tipo de datos óptimo para cada columna según los valores de la misma, por ejemplo, la columna se define como INT pero ¿es realmente necesario un entero o puede ser SMALLINT o incluso TINYINT. Otro ejemplo, ¿Una columna tiene valores NULL o puede ser definida como NOT NULL? lo que reduce el espacio necesario y se acelera el proceso en la mayoría de los casos.
Estas tareas y otras similares se hacen a menudo "a pala", mientras que en realidad MySQL ya tiene una función nativa para realizar la misma: PROCEDURE ANALYSE.
A continuación se muestra un pequeño ejemplo realizado sobre una tabla de la base de datos ejemplo World:
SELECT * FROM CountryLanguage procedure analyse() G
*************************** 1. row ***************************
Field_name: world.CountryLanguage.CountryCode
Min_value: ABW
Max_value: ZWE
Min_length: 3
Max_length: 3
Empties_or_zeros: 0
Nulls: 0
Avg_value_or_avg_length: 3.0000
Std: NULL
Optimal_fieldtype: ENUM('ABW','AFG','AGO','AIA','ALB','AND','ANT','ARE','ARG','ARM','ASM','ATG','AUS','AUT','AZE','BDI','BEL','BEN','BFA','BGD','BGR','BHR','BHS','BIH','BLR','BLZ','BMU','BOL','BRA','BRB','BRN','BTN','BWA','CAF','CAN','CCK','CHE','CHL','CHN','CIV','CMR','COD','COG','COK','COL','COM','CPV','CRI','CUB','CXR','CYM','CYP','CZE','DEU','DJI','DMA','DNK','DOM','DZA','ECU','EGY','ERI','ESH','ESP','EST','ETH','FIN','FJI','FLK','FRA','FRO','FSM','GAB','GBR','GEO','GHA','GIB','GIN','GLP','GMB','GNB','GNQ','GRC','GRD','GRL','GTM','GUF','GUM','GUY','HKG','HND','HRV','HTI','HUN','IDN','IND','IRL','IRN','IRQ','ISL','ISR','ITA','JAM','JOR','JPN','KAZ','KEN','KGZ','KHM','KIR','KNA','KOR','KWT','LAO','LBN','LBR','LBY','LCA','LIE','LKA','LSO','LTU','LUX','LVA','MAC','MAR','MCO','MDA','MDG','MDV','MEX','MHL','MKD','MLI','MLT','MMR','MNG','MNP','MOZ','MRT','MSR','MTQ','MUS','MWI','MYS','MYT','NAM','NCL','NER','NFK','NGA','NIC','NIU','NLD','NOR','NPL','NRU','NZL','OMN','PAK','PAN','PCN','PER','PHL','PLW','PNG','POL','PRI','PRK','PRT','PRY','PSE','PYF','QAT','REU','ROM','RUS','RWA','SAU','SDN','SEN','SGP','SHN','SJM','SLB','SLE','SLV','SMR','SOM','SPM','STP','SUR','SVK','SVN','SWE','SWZ','SYC','SYR','TCA','TCD','TGO','THA','TJK','TKL','TKM','TMP','TON','TTO','TUN','TUR','TUV','TWN','TZA','UGA','UKR','UMI','URY','USA','UZB','VAT','VCT','VEN','VGB','VIR','VNM','VUT','WLF','WSM','YEM','YUG','ZAF','ZMB','ZWE') NOT NULL
*************************** 2. row ***************************
Field_name: world.CountryLanguage.LANGUAGE
Min_value: Abhyasi
Max_value: [South]Mande
Min_length: 2
Max_length: 25
Empties_or_zeros: 0
Nulls: 0
Avg_value_or_avg_length: 7.1606
Std: NULL
Optimal_fieldtype: ENUM('Abhyasi','Acholi','Adja','Afar','Afrikaans','Aimar�','Ainu','Aizo','Akan','Albaniana','Ambo','Amhara','Ami','Ane','Arabic','Arabic-French','Arabic-French-English','Araucan','Arawakan','Armenian','Asami','Assyrian','Atayal','Avarian','Azerbaijani','Bajad','Bajan','Bakhtyari','Balante','Bali','Balochi','Bambara','Bamileke-bamum','Banda','Banja','Bari','Bariba','Bashkir','Basque','Bassa','Batakki','Beja','Belorussian','Bemba','Bengali','Berberi','Bhojpuri','Bicol','Bilin','Bislama','Boa','Brahui','Bubi','Bugi','Bulgariana','Bullom-sherbro','Bura','Burmese','Buryat','Busansi','Cakchiquel','Canton Chinese','Caprivi','Caribbean','Carolinian','Catalan','Cebuano','Chaga and Pare','Chakma','Chamorro','Chechen','Chewa','Chibcha','Chichewa','Chilluk','Chin','Chinese','Chiu chau','Chokwe','Chuabo','Chuvash','Circassian','Comorian','Comorian-Arabic','Comorian-French','Comorian-madagassi','Comorian-Swahili','Creole English','Creole French','Crioulo','Cuna','Czech','Czech and Moravian','Dagara','Danish','Dari','Dariganga','Dhivehi','Dinka','Diola','Dong','Dorbet','Duala','Dusun','Dutch','Dyula','Dzongkha','Edo','Embera','English','Eskimo Languages','Estonian','Ewe','Fang','Faroese','Fijian','Finnish','Fon','French','Fries','Friuli','Fukien','Ful','Fur','Futuna','Ga-adangme','Gaeli','Gagauzi','Galecian','Ganda','Garifuna','Garo','Gbaya','Georgiana','German','Gilaki','Gio','Gisu','Goajiro','Gogo','Gorane','Grebo','Greek','Greenlandic','Guaran�','Guaym�','Gujarati','Gur','Gurage','Gurma','Gusii','Ha','Hadareb','Hadjarai','Haiti Creole','Hakka','Hassaniya','Hausa','Haya','Hebrew','Hehet','Herero','Hiligaynon','Hindi','Hindko','Hui','Hungarian','Iban','Ibibio','Ibo','Icelandic','Ijo','Ilocano','Indian Languages','Irish','Italian','Japanese','Javanese','Joruba','Kaby�','Kachin','Kalenjin','Kamba','Kanem-bornu','Kannada','Kanuri','Karakalpak','Karen','Kavango','Kayah','Kazakh','Kekch�','Ket�ua','Khasi','Khmer','Khoekhoe','Kiga','Kikuyu','Kirgiz','Kiribati','Kirundi','Kissi','Kongo','Kono-vai','Korean','Kosrean','Kotokoli','Kpelle','Kru','Kuranko','Kurdish','Kuy','Kymri','Lango','Lao','Lao-Soung','Latvian','Lezgian','Limba','Lithuanian','Loma','Lomwe','Lotuko','Lozi','Luba','Luchazi','Lugbara','Luguru','Luhya','Luimbe-nganguela','Luo','Luri','Luvale','Luxembourgish','Macedonian','Madura','Maguindanao','Mahor�','Maithili','Maka','Makonde','Makua','Malagasy','Malajalam','Malay','Malay-English','Malenasian Languages','Malinke','Maltese','Mam','Man','Mandara','Mandarin Chinese','Mandjia','Mandyako','Mano','Mant�u','Maori','Maranao','Marathi','Marendje','Mari','Marma','Marshallese','Masai','Masana','Maya Languages','Mayo-kebbi','Mazandarani','Mbete','Mboshi','Mbum','Mbundu','Mende','Meru','Miao','Min','Minangkabau','Miskito','Mixed Languages','Mixtec','Moba','Mon','Mon-khmer','Monegasque','Mongo','Mongolian','Moravian','Mordva','Mortlock','Mossi','Mpongwe','Muong','Nahua','N�huatl','Nama','Naudemba','Nauru','Ndebele','Nepali','Newari','Ngala and Bangi','Ngbaka','Ngoni','Niue','Nkole','Northsotho','Norwegian','Nsenga','Nubian Languages','Nuer','Nung','Nyakusa','Nyamwesi','Nyaneka-nkhumbi','Nyanja','Nyika','Orija','Oromo','Osseetti','Otom�','Ouaddai','Ovambo','Ovimbundu','Paiwan','Palau','Pampango','Pangasinan','Papiamento','Papuan Languages','Pashto','Persian','Philippene Languages','Pilipino','Pitcairnese','Pohnpei','Polish','Polynesian Languages','Portuguese','Punjabi','Punu','Punu-sira-nzebi','Puyi','Quich�','Rakhine','Rapa nui','Romani','Romanian','Romansh','Ronga','Rundi','Russian','Rwanda','Saame','Saho','Samoan','Samoan-English','San','Sango','Santhali','Sara','Saraiki','Sardinian','Sena','Senufo and Minianka','Serbo-Croatian','Serer','Seselwa','Shambala','Shan','Shona','Sidamo','Silesiana','Sinaberberi','Sindhi','Singali','Slovak','Slovene','Soga','Somali','Somba','Songhai','Songhai-zerma','Soninke','Soqutri','Sotho','Southern Slavic Languages','Southsotho','Spanish','Sranantonga','Sumo','Sunda','Susu','Swahili','Swazi','Swedish','Tadzhik','Tagalog','Tahitian','Tamang','Tamashek','Tamil','Tandjile','Tatar','Teke','Telugu','Temne','Teso','Thai','Tharu','Tho','Tibetan','Tigre','Tigrinja','Tikar','Tiv','Tokelau','Tongan','Tripuri','Trukese','Tsonga','Tswa','Tswana','Tujia','Tukulor','Turkana','Turkish','Turkmenian','Tuvalu','T�am','Udmur','Uighur','Ukrainian','Ukrainian and Russian','Urdu','Uzbek','Venda','Vietnamese','Walaita','Wallis','Waray-waray','Warrau','Watyi','Wolea','Wolof','Xhosa','Yalunka','Yao','Yap','Yi','Yucatec','Zande','Zapotec','Zenaga','Zhuang','Zulu','[South]Mande') NOT NULL
*************************** 3. row ***************************
Field_name: world.CountryLanguage.IsOfficial
Min_value: F
Max_value: T
Min_length: 1
Max_length: 1
Empties_or_zeros: 0
Nulls: 0
Avg_value_or_avg_length: 1.0000
Std: NULL
Optimal_fieldtype: ENUM('F','T') NOT NULL
*************************** 4. row ***************************
Field_name: world.CountryLanguage.Percentage
Min_value: 0.1
Max_value: 100.0
Min_length: 3
Max_length: 5
Empties_or_zeros: 65
Nulls: 0
Avg_value_or_avg_length: 20.4
Std: 30.8
Optimal_fieldtype: FLOAT(4,1) NOT NULL
4 rows IN SET (0.01 sec)
La salida de PROCEDURE ANALYSE (o cualquier herramienta similar) no debe ser tomado como un determinante para tomar una acción, sino más bien utilizado como base para tomar nuestras propias decisión.
Hay que considerar que aveces cuando nos sugiere un TINYINT en vez de un INT, puede ser que ese número se vaya a incrementar bastante con el paso del tiempo y no sea apropiado combiarlo.
También hay que tener muchos cuidados en el abuso de los ENUM en la recomendaciones, pues muchas veces nos estariamos limitando a un número fijo de opciones, cuando en realidad un CHAR nos permitirá nuevos valores. Lo mismo ocurre con la longitud de los campos CHAR o VARCHAR, que en todos los casos el dimensionamiento de los mismos fue dado según los datos que espera la tabla a futuro.
En general, a pesar de que los resultados de esta herramienta no dan para hacer inmediatamente un ALTER TABLE, proporciona información muy útil para la realizar un esquema de auditoría.
Comentarios: