You might need INFORMATION_SCHEMA.KEY_COLUMN_USAGE
You would have to issue this query
SELECT column_name
FROM information_schema.key_column_usage
WHERE table_schema='$db'
AND table_name='$table'
AND constraint_name='PRIMARY';
This will retrieve every column in the PRIMARY KEY
.
You could then make this query generate the ALTER TABLE
clauses for you as follows:
SET group_concat_max_len = 1048576;
SELECT GROUP_CONCAT(CONCAT('MODIFY COLUMN ',column_name,' DEFAULT NULL'))
FROM information_schema.key_column_usage
WHERE table_schema='$db'
AND table_name='$table'
AND constraint_name='PRIMARY';
This will produce a comma-separated list of MODIFY COLUMN
clauses you need to apply to the column after dropping the PRIMARY KEY
. If you want to drop any of these columns, you have to change MODIFY COLUMN
to DROP COLUMN
for the columns that need to be dropped.
Give it a Try !!!
UPDATE 2014-12-09 14:00 EST
Your comment
I'm trying to understand how this works. GROUP_CONCAT(CONCAT('MODIFY COLUMN ',column_name,' DEFAULT NULL')) is especially confusing to me. Where does column_name come from in this query? I tried running it as is in MySQL, but I get no results
To give you a general idea of how query can help you, here is a table in MySQL on my laptop
mysql> show create table weird.vinner\G
*************************** 1. row ***************************
Table: vinner
Create Table: CREATE TABLE `vinner` (
`startnr` int(11) NOT NULL,
`alder` varchar(25) NOT NULL,
`kjonn` varchar(25) NOT NULL,
`ovelseid` varchar(25) NOT NULL,
`slutttid` int(11) NOT NULL,
PRIMARY KEY (`startnr`,`slutttid`),
KEY `slutttid` (`slutttid`),
CONSTRAINT `vinner_ibfk_1` FOREIGN KEY (`slutttid`) REFERENCES `passering` (`slutttid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
See the PRIMARY KEY. It has two columns: startnr
and slutttid
.
Now, if I run my code on that tabl, I get this list
mysql> SET group_concat_max_len = 1048576;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT GROUP_CONCAT(CONCAT('MODIFY COLUMN ',column_name,' DEFAULT NULL'))
-> FROM information_schema.key_column_usage
-> WHERE table_schema='weird'
-> AND table_name='vinner'
-> AND constraint_name='PRIMARY';
+------------------------------------------------------------------------+
| GROUP_CONCAT(CONCAT('MODIFY COLUMN ',column_name,' DEFAULT NULL')) |
+------------------------------------------------------------------------+
| MODIFY COLUMN startnr DEFAULT NULL,MODIFY COLUMN slutttid DEFAULT NULL |
+------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql>
The output creates a MODIFY COLUMN clause for both columns.
If you were dropping the slutttid column, you would use PHP to change MODIFY
to DROP
MODIFY COLUMN startnr DEFAULT NULL,DROP COLUMN slutttid
You would be doing this kind of code to generate the clauses needed
You're using mysql 5.1, This means the only engines you'll have available are MyISAM or innodb. in both cases adding a new column, regardless of nullability will require a complete, blocking, table rebuild during alter table.
You maybe be able to use the pt-online-schema change tool that does some tricks to rebuild the table in a less blocking manner but may not work out if you have complicated composite primary keys.
If you have a more recent version (5.6.22 Percona Build) you could use a tokudb storage engine that allows you to to "instantly" add columns. The way it's indexing works it propagates changes down as they're accessed.
Best Answer
I don't think there is such an option. You could request such at bugs.mysql.com.
I disagree with making NULL (or, for that matter) NOT NULL mandatory. NULL and NOT NULL have important uses in schema design and execution.
PRIMARY KEYs
must beNOT NULL
, and that is implicitly provided. Due to business logic, some columns should not be left out; some should be allowed to be optional.NULL
has a lot of different semantics, and arbitrarily forcing all columns to beNULL
begs the issue of which semantics you want. Examples: Optional (product specifications); not yet provided (anend_date
); unknown (due to partial data received).