How to change a primary key in SQL to auto_increment? - sql

I have a table in MySQL that has a primary key:
mysql> desc gifts;
+---------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+-------------+------+-----+---------+-------+
| giftID | int(11) | NO | PRI | NULL | |
| name | varchar(80) | YES | | NULL | |
| filename | varchar(80) | YES | | NULL | |
| effectiveTime | datetime | YES | | NULL | |
+---------------+-------------+------+-----+---------+-------+
but I wanted to make it auto_increment.
The following statement failed. How can it be modified so that it can work? thanks
mysql> alter table gifts modify giftID int primary key auto_increment;
ERROR 1068 (42000): Multiple primary key defined

Leave off the primary key attribute:
ALTER TABLE gifts MODIFY giftID INT AUTO_INCREMENT;
Certain column attributes, such as PRIMARY KEY, aren't exactly properties of the column so much as shortcuts for other things. A column marked PRIMARY KEY, for example, is placed in the PRIMARY index. Futhermore, all columns in the PRIMARY index are given the NOT NULL attribute. (Aside: to have a multi-column primary key, you must use a separate constraint clause rather than multiple PRIMARY KEY column attributes.) Since the column is already in the PRIMARY index, you don't need to specify it again when you modify the column. Try SHOW CREATE TABLE gifts; to see the affects of using the PRIMARY KEY attribute.

Related

MariaDB foreign key auto generated index not created for the first column of PK

i'm facing a question without answer. I can't understand why the auto generated index from the FK creation is not working when the column seems to be the first one of PK, what i mean :
Create a simple schema with :
CREATE TABLE cat (name VARCHAR(255) PRIMARY KEY);
CREATE TABLE dog (name VARCHAR(255) PRIMARY KEY);
CREATE TABLE cat_dog_couple
(
cat_name VARCHAR(255),
dog_name VARCHAR(255),
PRIMARY KEY (cat_name, dog_name),
CONSTRAINT fk__cat_dog_couple__cat_name FOREIGN KEY (cat_name) references cat(name),
CONSTRAINT fk__cat_dog_couple__dog_name FOREIGN KEY (dog_name) references dog(name)
);
These indexes will be generated :
+----------------+------------+------------------------------+--------------+-------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name |
+----------------+------------+------------------------------+--------------+-------------+
| cat_dog_couple | 0 | PRIMARY | 1 | cat_name |
| cat_dog_couple | 0 | PRIMARY | 2 | dog_name |
| cat_dog_couple | 1 | fk__cat_dog_couple__dog_name | 1 | dog_name |
+----------------+------------+------------------------------+--------------+-------------+
Screen show index
I don't really understand why the index fk__cat_dog_couple__cat_name is not created?
Is it a bug ? A technical limitation ? A technical choice ?
Tested on MariaDB 10.4.x and 10.5.x.

How to scan join query results into a struct containing a slice of structs using sqlx

Here are the tables that are relevant to this question:
lists:
Table "public.lists"
Column | Type | Collation | Nullable | Default
-------------+--------+-----------+----------+-------------------
id | uuid | | not null | gen_random_uuid()
user_id | uuid | | not null |
list_name | text | | not null |
description | text | | not null |
created_at | bigint | | not null |
updated_at | bigint | | not null |
Indexes:
"lists_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
"fk_user_id" FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL
Referenced by:
TABLE "todos" CONSTRAINT "fk_list_id" FOREIGN KEY (list_id) REFERENCES lists(id) ON DELETE SET NULL
and todos:
Table "public.todos"
Column | Type | Collation | Nullable | Default
------------+---------+-----------+----------+-------------------
id | uuid | | not null | gen_random_uuid()
list_id | uuid | | not null |
user_id | uuid | | not null |
content | text | | not null |
done | boolean | | not null | false
created_at | bigint | | not null |
updated_at | bigint | | not null |
Indexes:
"todos_pkey" PRIMARY KEY, btree (id)
"todos_content_key" UNIQUE CONSTRAINT, btree (content)
Foreign-key constraints:
"fk_list_id" FOREIGN KEY (list_id) REFERENCES lists(id) ON DELETE SET NULL
"fk_user_id" FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL
and these are the structs that I would ideally like to use:
type Todo struct {
ID string `db:"id"`
ListID string `db:"list_id"`
UserID string `db:"user_id"`
Content string `db:"content"`
Done bool `db:"done"`
CreatedAt int64 `db:"created_at"`
UpdatedAt int64 `db:"updated_at"`
}
type ListWithTodos struct {
ID string `db:"id"`
UserID string `db:"user_id"`
ListName string `db:"list_name"`
Description string `db:"description"`
Todos []Todo
CreatedAt int64 `db:"created_at"`
UpdatedAt int64 `db:"updated_at"`
}
What I would like to do is select a list and add all of its children todos (todos with a list_id equal to the list's id) to the field ListWithTodos.Todos. I currently have this query which returns all of the todos with the parent list attached (and I know this won't work with the struct I have):
SELECT l.*, t.* FROM lists l RIGHT JOIN todos t ON l.id=t.list_id WHERE l.id='insert uuid here';
and my go code and structs obviously don't work with the query.
What query would I use to get the results into a single struct and what sqlx functions would I use to do this?

SQL Server Conditional Foreign Key

I have two tables in my SQL Server database, Foo and Bar. Table Foo is like so:
+-------+
| Foo |
+-------+
| Id |
| Type |
| Value |
+-------+
The table has values like:
+----+--------+-----------+
| Id | Type | Value |
+----+--------+-----------+
| 1 | Status | New |
| 2 | Status | Old |
| 3 | Type | Car |
| 4 | State | Inventory |
| 5 | State | Sold |
+----+--------+-----------+
The table Bar is like so:
+----------+
| Bar |
+----------+
| Id |
| TypeId |
| StatusId |
| StateId |
+----------+
Where TypeId, StatusId and StateId are all foreign key'ed to the Foo table.
But I want to put a condition on each foreign key where they can only key to the Foo
ids related to it's type. For example, the TypeId column can ONLY foreign key to id
3 on the Foo table. Or the StatusId column can ONLY foreign key to ids 1 or 2.
I know there is a check function in SQL Server but I'm unsure on how to use it correctly. I
tried to do something like this:
CREATE TABLE TEST.dbo.Bar
(
Id int PRIMARY KEY NOT NULL IDENTITY,
TypeId int NOT NULL CHECK (Type='Type'),
CONSTRAINT FK_Bar_Foo_Type FOREIGN KEY (TypeId) REFERENCES Foo (Id, Type)
)
CREATE UNIQUE INDEX Bar_Id_uindex ON TEST.dbo.Bar (Id)
But this didn't work. What am I doing wrong?
The check constraints you are referring to are only used to limit the type of information stored in a key or non key column. So, if you don't want a key column to have a negative value (lets say its a price column, and there is never a negative price) you will use Check constraint.
To better understand the concept of primary and foreign keys:
Primary key uniquely identifies each record in a table.
Foreign key is a value in some table which is a unique identifier (and can also be a primary key) in another table. This means that Foreign key can repeat many times in the table in which it is a foreign key in, and it will definitely be unique in the table that it is created from ( in the table that gives meaning to it).
Now coming to your question, you probably need to use the concept of composite keys. A composite key is basically a group of two or more values that uniquely identify a record, because you cannot enforce limitations on foreign keys in the way you are intending to do, because that defeats the very purpose of a key. Handle some issues with type of data stored in your keys at the application layer instead of database layer.
Looking at the problem in this manner will conceptually resolve some design flaws with your tables as as well.

How do I enforce referential integrity on a type 6 SCD Dimension table?

I'm having difficulties with designing the Primary and Foreign key relationship between my fact table and a Type 6 SCD Dimension table.
The dimension table has the following definition:
CREATE TABLE DimTable
(
surrogate_key INT,
row_key INT IDENTITY (1,1),
natural_key INT NOT NULL,
current_value INT NOT NULL,
historic_value INT NOT NULL,
is_current BIT NOT NULL,
record_start_date_id INT NOT NULL,
record_end_date_id INT NOT NULL
-- Primary Key
CONSTRAINT pk_dimtable_surrogate_key_row_key PRIMARY KEY (surrogate_key, row_key);
A sample of how the data looks like:
surrogate_key | row_key | natural_key | current_value | historic_value | is_current | record_start_date_id | record_end_date_id
-------------------------------------------------------------------------------------------------------------------------------
121 | 2591227 | 123456 | 20090807 | 20090807 | 0 | 20180807 | 99991231
121 | 2591228 | 123456 | 20140807 | 20090807 | 0 | 20180807 | 99991231
121 | 2591229 | 123456 | 20141107 | 20140807 | 1 | 20180807 | 99991231
122 | 2591230 | 456789 | 20090807 | 20090807 | 1 | 20180807 | 99991231
From my understanding of the wikipedia page, I should be able to enforce Referential integrity through PK/FK relationship, however the master surrogate key is not unique across this table so I don't know how to point the surrogate_id in my fact table to the surrogate_key with a FK constraint.
Is there any way around this limitation, or do I understand the description wrong?
Btw, this is my first time asking a question here, so if anything is unclear or missing please let me know!
EDIT: Column names are generic dummynames. The actual colnames are more descriptive.
I believe you misunderstood the concept of SurrogateKey. Instead the Row_Key attribute here makes more sense of SurrogateKey.
I suggest go one and read books to understand the surrogate key. You may require lot of changes in your process.

SQL: What is does the UNIQUE mean when creating a primary key

I've got a table called students:
+------------+------------+-----------+---------------------+---------------------+
| student_id | first_name | surname | email | reg_date |
+------------+------------+-----------+---------------------+---------------------+
| 1 | Emily | Jackson | emilyj#gmail.com | 2012-10-14 11:14:13 |
| 2 | Daniel | ALexander | daniela#hotmail.com | 2014-08-19 08:08:23 |
| 3 | Sarah | Bell | sbell#gmail.com | 1998-07-04 13:16:32 |
| 4 | Alex | Harte | AHarte#hotmail.com | 1982-06-14 00:00:00 |
+------------+------------+-----------+---------------------+---------------------+
When creating the table:
CREATE TABLE students(
-> student_id INT NOT NULL AUTO_INCREMENT,
-> first_name VARCHAR(30) NOT NULL,
-> surname VARCHAR(50) NOT NULL,
-> email VARCHAR(200) NOT NULL,
-> reg_date DATETIME NOT NULL,
-> PRIMARY KEY (student_id),
-> UNIQUE (email));
What does the 'UNIQUE (email)' mean? Does it mean if the primary key isn't unique, look at the email to see if that's unique instead? Or something different?
Thanks
The UNIQUE keyword creates a unique constraint on the columns that are mentioned in its argument list (in this case, email). It does not interfere with the primary key. It will enforce unique values on the email column, that is, fail with an exception when a row is about to be INSERTed (or UPDATEd) that would collide with an existing row.
A primary key (by default) implies a unique constraint. So as you designate student_id as your primary key, the RDBMS will also automatically maintain unique values in that column for you.
Further reading: http://www.w3schools.com/sql/sql_unique.asp
It allows the engine to use it as an index in queries and enforces it to be unique when a record/s are inserted/updated; throwing a violation of a unique key constraint when an already existing email is inserted/updated.
Example: http://sqlfiddle.com/#!9/7a0aee
More Information: http://dev.mysql.com/doc/refman/5.7/en/partitioning-limitations-partitioning-keys-unique-keys.html