Does Adding a Primary Key to a table checks default columns? - mysql

I tried to add primary key in a table and set it as a column that has default value and is not null and is not unique.MySQL accepted that column as Primary Key...I want to know that this is wrong as if a user enters 2 records having default values he will not be able to do so..Is this a problem where SQL should have checked column as non default values or this is a designer end problem that default columns should not be made Primary Key...?

I'm not fully understanding the problem. You have declared a column to be a primary key that has these characteristics:
NOT NULL
Default value
A primary key imposes these characteristics:
NOT NULL
Unique
These characteristics are not mutually incompatible. The only issue is that the default value can only be assigned once in the column. The second time you try to insert a row with the default value, you will get a violation of the uniqueness constraint.
In other words, MySQL (and I think other databases as well) allow you declare this even if it doesn't seem like a good idea.

Null:
every column that is flagged wiht NULL is just specified that this column may contain a NULL value. The column can still have another default value.
Primary key:
A PK is always treated unique and you cannot have two identical values on a row
There can only be one PK per table, its the main index which is very fast when querying the table on its primary column.
A PK is always a single column and cannot be spread over multiple columns as every other index (unique or usual index) can do.
A PK column cannot accept NULL values
Sample:
ID (INT, PK) | Name (varchar)
1 | Foo ->Valid
2 | Bar ->Valid
2 | FooBar ->Invalid (Duplicate Primary key value ID)
Conclusion: Yes MySQL should and will throw an error at second attempt to put a default value because its simply treated UNIQUE and a given default value is const. The MySQL server will attempt to insert the default value when you dont specify any value for this column in your insert statement.
Pretty much means: A PrimaryKey column with a default value makes no sense, except you use an auto-increment which is a pseudo "default value" which is different each time you try to insert something.
I hope this answers your questions

Related

Using two columns as primary key. Can I keep one column empty?

I have a requirement where I need to uniquely identify a row based on two columns.
nType | dType | severity
------+-------+----------
down | 6500 | CRITICAL
Combination of nType and dType should always be unique. So, I created a table using
CREATE TABLE IF NOT EXISTS severitymapping(nType text, dType text, severity text,
PRIMARY KEY (nType, dType);
But there can be a case when dType is empty. So, that too is unique for my business logic. But database will not allow empty/null value of dType in the database.
Is there a way to achieve this?
For MySQL only (the question is MySQL-tagged).
Primary key expression cannot include NULLable columns.
If you need some column value to be NULL (not "empty" - there is no such term in SQL) then you cannot create PRIMARY key which includes this column. But you may create UNIQUE index - it allows NULLs. In this case you need in another expression to be primary key - autoincremented synthetic PK is reasonable.
Also the datatype for each column must be reasonable - the values shown and TEXT datatype does not match this. VARCHAR for nType and INT for dType looks like more suitable.
And TEXT column cannot be used in the index without the indexed prefix length specified.
So use something close to
CREATE TABLE IF NOT EXISTS severitymapping(
nType VARCHAR(255),
dType INT,
severity TEXT,
UNIQUE (nType, dType),
id INT AUTO_INCREMENT PRIMARY KEY
);
It isn't possible to have a null or empty value for any of the columns in a primary key in Cassandra.
The partition key (nType) uniquely identifies the partition and its hash value determines the node on which it is stored.
The clustering key (dType) uniquely identifies a row within a partition. Without it, it is not possible to store the row in the partition because the row cannot be retrieved without the clustering key. Cheers!
In your case, you are keeping nType as the partition key and dType as the clustering key.
Cassandra does not allow null clustering key values.
If you really need "no value" for some reason, then use an empty string OR some other special literal value like 'UNDEFINED' to cluster those together.
This question can help you too.

Confusion Regarding Primary Key in Mysql?

I am learning about SQL and using Mysql to work out the queries. On topic of Primary Key, I read that
Whichever column is declared as Primary Key, it can not be null.
So, I made a simple employee table with fields id and name with PRIMARY KEY as id;
And put in the following queries,
INSERT INTO employee (id, name) VALUES (1, 'John');
INSERT INTO employee (id, name) VALUES (2, 'Frank');
Now to test the primary key column not being Null property I put in the following query.
INSERT INTO employee(name) VALUES('Joe');
Turns out no error was shown and the query ran successfully
Upon selecting the records from the whole table I see
id |name
0 | Joe
1 | John
2 | Frank
I was expecting to see error something like
Column 'id' cannot be NULL
but as you can see, Primary Key for Joe was automatically set to 0.
I try inserting again it with not giving id
Now I get the message,
Duplicate entry for '0' for key 'PRIMARY'
So what happened here? And Doesn't Primary key begins from 1?
MySQL (before 5.7) uses an implicit default value of 0 for your primary key, see the documentation:
If the column cannot take NULL as the value, MySQL defines the column with no explicit DEFAULT clause. Exception: If the column is defined as part of a PRIMARY KEY but not explicitly as NOT NULL, MySQL creates it as a NOT NULL column (because PRIMARY KEY columns must be NOT NULL). Before MySQL 5.7.3, the column is also assigned a DEFAULT clause using the implicit default value. To prevent this, include an explicit NOT NULL in the definition of any PRIMARY KEY column.
If you insert null into such a column, the implicit value is taken, unless you set strict mode:
For data entry into a NOT NULL column that has no explicit DEFAULT clause [...]
If strict SQL mode is enabled, an error occurs for transactional tables and the statement is rolled back. For nontransactional tables, an error occurs, but if this happens for the second or subsequent row of a multiple-row statement, the preceding rows will have been inserted.
If strict mode is not enabled, MySQL sets the column to the implicit default value for the column data type.
The implicit default value for numeric types is 0. So every time you use null (or not use the column at all), MySQL uses 0. This works the first time, but not the second time.
You've set the AUTO_INCREMENT attribute on the id field. That's a nice little feature that ensures the value is always unique so you don't have to worry about it being null, and worry about stuff that matters. But if you try this, errors will surely be thrown at you;
INSERT INTO `employee` (`id`, `name`) VALUES (null, `Joe`);
EDIT Ah, I didn't really see the error you posted. What happened here; you did actually not set the AUTO_INCREMENT attribute (although you should have ;)). Now, the id field is an integer field. If you do not give any value, mysql tries to save your ass by giving it the most probable value, or most close to no value at all, which is 0. The first time all is well, the second time it sees the value is already present, and it fails.

How to alter the table that can accept not null values

Can you please tell How to alter the table so that it can accept the not null constraint
alter table customer add emp_id int not null foreign key references emp(emp_id)
I have tried as above, but it is showing error:
Msg 4901, Level 16, State 1, Line 1
ALTER TABLE only allows columns to be added that can contain nulls, or have a DEFAULT definition specified, or the column being added is an identity or timestamp column,
or alternatively if none of the previous conditions are satisfied the table must be
empty to allow addition of this column. Column 'emp_id1' cannot be added to non-empty table 'customer' because it does not satisfy these conditions.
The error is pretty clear.
You are trying to add a non-null column to a table that has data. When you add the column, it has no value. So, the default value is put into the table for the existing rows. There is no default value, so NULL is used.
You can solve this in a few ways. One would be to empty the table truncate table customer, add the new column, then load the data again.
Another way would be to add the column with NULL allowed. Then fill in the value everywhere and then add the NOT NULL constraint.

MySQL: UNIQUE, but DEFAULT NULL - allowed by creating of table. More than 1 NULL is allowed to insert. Why?

I've just checked and it's allowed to create a table with a column that is NULL by default, although it's a UNIQUE KEY at the same time:
CREATE TABLE IF NOT EXISTS `u789` (
`column1` varchar(10) DEFAULT NULL,
UNIQUE KEY (column1)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
As I understand, it looks odd and has not much sense. I expected the second insert of
INSERT INTO u789 VALUE (NULL);
will fail.
But, it inserts first, second, third NULL value without any problems. Who can explain me why it iserts second and third columns if NULL is already in the table?
This is a theoretical question (as I understand nobody uses DEFAULT NULL + UNIQUE KEY for the same column in most situations), but I want to understand why it doesn't throw an error once one NULL is already in the column. Am I doing something wrong with declaring a unique column?
Thank you.
According to the SQL 92 specification (and how you read it) unique constraints are meant to denote candidate keys and therefore should not allow duplicate values nor NULL values. DB2 implements their unique constraints in this manner. More than a few database vendors (including MySQL) read the specification as ignoring NULL values much like the Group By clause ignores NULL values and thus they implement unique constraints such that it only applies to non-NULL values. Still others, treat the NULL as its own special value and only allow one entry which is NULL. Microsoft SQL Server implements unique constraints this way. The only aspect that is consistent amongst all vendors with respect to unique constraints is that non-NULL values must be unique.
Because NULL is not equal to NULL. Even though some RDMS, SQLServer for instance, treat 2 NULLs as equal when it comes to unique constraints.

MySQL Integer column, unique values but default possibility?

I want a table with an integer column, that may or may not be filled (it is a social security number). But if it is filled, I want it to be UNIQUE : there cannot be two entries of the same number.
Using a unique constraint won't work cause integer won't accept NULL values, and MySQL detects multiple 0 values.
How can I set a unique constraint on an integer with a default value ? Or how can I set the integer column to accept NULL values ? (this question takes it for granted : MySQL Foreign Key Constraint - Integer Column but I can't)
create table test (
myint INT NULL, UNIQUE INDEX (myint)
);
This will allow a unique constraint on any integers added but will allow multiple NULL values to be entered.
MySQL treats NULL as 'unknown' value so cant possibly do a comparison to see if a like value is already there 'unknown' !== 'unknown'.
This also depends on which database engine you are using, the above holds true for MyISAM and InnoDB
Please see the code below:
ALTER TABLE test MODIFY myint INT NULL
ALTER TABLE test ADD UNIQUE INDEX (myint)
It works when data inputs are directly from MySQL (PHPMyadmin), saved as NULL, but a php script saves it as zeroes, and so it does not allow multiple entries.