kdb primary key unique - primary-key

Why there is no uniqueness constraint in kdb primary keys? Below I can create two rows with primary key column sym
kt:([sym:`a`b`c`c]name:`alpha`beta`gamma`zeta);
kt
©¬ sym name
a alpha
b beta
c gamma
c zeta

From the kx wiki on keyed tables
Keys should be unique but (sadly) this is not enforced. As we have already noted, dictionary creation does not enforce key uniqueness. A value row associated with a duplicate key is not accessible via key lookup, but it can be retrieved via a select on the key column.
Here’s the kx wiki reference for non-unique keys and values

Generally you will find that kdb won't hold your hand - if you need rule enforcement you have to set it up yourself.
You can use a u# (unique) attribute to enforce key uniqueness:
q)kt:([sym:`a`b`c]name:`alpha`beta`gamma);
q)update `u#sym from `kt
`kt
q)`kt insert (`c;`zeta)
'insert
[0] `kt insert (`c;`zeta)
^
q)`kt insert (`d;`zeta)
,3
q)kt
sym| name
---| -----
a | alpha
b | beta
c | gamma
d | zeta

Related

Postgres - add sequential column to existing data

I have an existing table that currently doesn't have an id column and a lot of duplicate rows on what should be a unique pair - it's messy. Example:
fips | customer_id
-------+------------
17043 | 2085
17043 | 2085
42091 | 4426
42091 | 4426
customer_id/fips should be unique, but the current code and schema don't enforce that. There also isn't an id column, so I have no unique way to reference a single row.
I'd like to add an id column and assign sequential integers so I can have a unique primary key. How can I go about that?
Postgres 10 added IDENTITY columns (as demonstrated in Gordon's answer).
In Postgres 9.6 (or any version) you can use use a serial column instead.
Either way, make it the PRIMARY KEY in the same command. That's cheaper for big tables:
ALTER TABLE tbl ADD COLUMN tbl_id serial PRIMARY KEY;
Or:
ALTER TABLE tbl ADD COLUMN tbl_id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY;
db<>fiddle here
IDENTITY columns are not PRIMARY KEY automatically. Postgres allows multiple IDENTITY columns for the same table (even if that's rarely useful).
See:
Auto increment table column
Or you clean up the mess to make (fips, customer_id) unique. Then that can be your PK. See:
How to delete duplicate rows without unique identifier
You can simply add an identity column:
alter table t add column id int generated always as identity;
Here is a db<>fiddle.

Can a foreign key refer to a primary key in the same table?

I just think that the answer is false because the foreign key doesn't have uniqueness property.
But some people said that it can be in case of self joining the table.
I am new to SQL. If its true please explain how and why?
Employee table
| e_id | e_name | e_sala | d_id |
|---- |------- |----- |--------|
| 1 | Tom | 50K | A |
| 2 | Billy | 15K | A |
| 3 | Bucky | 15K | B |
department table
| d_id | d_name |
|---- |------- |
| A | XXX |
| B | YYY |
Now, d_id is foreign key so how it can be a primary key. And explain something about join. What is its use?
I think the question is a bit confusing.
If you mean "can foreign key 'refer' to a primary key in the same table?", the answer is a firm yes as some replied. For example, in an employee table, a row for an employee may have a column for storing manager's employee number where the manager is also an employee and hence will have a row in the table like a row of any other employee.
If you mean "can column(or set of columns) be a primary key as well as a foreign key in the same table?", the answer, in my view, is a no; it seems meaningless. However, the following definition succeeds in SQL Server!
create table t1(c1 int not null primary key foreign key references t1(c1))
But I think it is meaningless to have such a constraint unless somebody comes up with a practical example.
AmanS, in your example d_id in no circumstance can be a primary key in Employee table. A table can have only one primary key. I hope this clears your doubt. d_id is/can be a primary key only in department table.
This may be a good explanation example
CREATE TABLE employees (
id INTEGER NOT NULL PRIMARY KEY,
managerId INTEGER REFERENCES employees(id),
name VARCHAR(30) NOT NULL
);
INSERT INTO employees(id, managerId, name) VALUES(1, NULL, 'John');
INSERT INTO employees(id, managerId, name) VALUES(2, 1, 'Mike');
-- Explanation:
-- In this example.
-- John is Mike's manager. Mike does not manage anyone.
-- Mike is the only employee who does not manage anyone.
Sure, why not? Let's say you have a Person table, with id, name, age, and parent_id, where parent_id is a foreign key to the same table. You wouldn't need to normalize the Person table to Parent and Child tables, that would be overkill.
Person
| id | name | age | parent_id |
|----|-------|-----|-----------|
| 1 | Tom | 50 | null |
| 2 | Billy | 15 | 1 |
Something like this.
I suppose to maintain consistency, there would need to be at least 1 null value for parent_id, though. The one "alpha male" row.
EDIT: As the comments show, Sam found a good reason not to do this. It seems that in MySQL when you attempt to make edits to the primary key, even if you specify CASCADE ON UPDATE it won’t propagate the edit properly. Although primary keys are (usually) off-limits to editing in production, it is nevertheless a limitation not to be ignored. Thus I change my answer to:- you should probably avoid this practice unless you have pretty tight control over the production system (and can guarantee no one will implement a control that edits the PKs). I haven't tested it outside of MySQL.
Eg: n sub-category level for categories .Below table primary-key id is referred by foreign-key sub_category_id
A good example of using ids of other rows in the same table as foreign keys is nested lists.
Deleting a row that has children (i.e., rows, which refer to parent's id), which also have children (i.e., referencing ids of children) will delete a cascade of rows.
This will save a lot of pain (and a lot of code of what to do with orphans - i.e., rows, that refer to non-existing ids).
Other answers have given clear enough examples of a record referencing another record in the same table.
There are even valid use cases for a record referencing itself in the same table. For example, a point of sale system accepting many tenders may need to know which tender to use for change when the payment is not the exact value of the sale. For many tenders that's the same tender, for others that's domestic cash, for yet other tenders, no form of change is allowed.
All this can be pretty elegantly represented with a single tender attribute which is a foreign key referencing the primary key of the same table, and whose values sometimes match the respective primary key of same record. In this example, the absence of value (also known as NULL value) might be needed to represent an unrelated meaning: this tender can only be used at its full value.
Popular relational database management systems support this use case smoothly.
Take-aways:
When inserting a record, the foreign key reference is verified to be present after the insert, rather than before the insert.
When inserting multiple records with a single statement, the order in which the records are inserted matters. The constraints are checked for each record separately.
Certain other data patterns, such as those involving circular dependences on record level going through two or more tables, cannot be purely inserted at all, or at least not with all the foreign keys enabled, and they have to be established using a combination of inserts and updates (if they are truly necessary).
Adding to the answer by #mysagar the way to do the same in MySQL is demonstrated below -
CREATE TABLE t1 (
-> c1 INT NOT NULL,
-> PRIMARY KEY (c1),
-> CONSTRAINT fk FOREIGN KEY (c1)
-> REFERENCES t1 (c1)
-> ON UPDATE RESTRICT
-> ON DELETE RESTRICT
-> );
would give error -
ERROR 1822 (HY000): Failed to add the foreign key constraint. Missing index for constraint 'fk' in the referenced table 't1'
The correct way to do it is -
CREATE TABLE t1 (
-> c1 INT NOT NULL,
-> PRIMARY KEY (c1),
-> KEY i (c1),
-> CONSTRAINT fk FOREIGN KEY (c1)
-> REFERENCES t1 (c1)
-> ON UPDATE RESTRICT
-> ON DELETE RESTRICT
-> );
One practical utility I can think of is a quick-fix to ensure that after a value is entered in the PRIMARY KEY column, it can neither be updated, nor deleted.
For example, over here let's populate table t1 -
INSERT INTO t1 (c1) VALUES
-> (1),
-> (2),
-> (3),
-> (4),
-> (5);
SELECT * FROM t1;
+----+
| c1 |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
+----+
Now, let's try updating row1 -
UPDATE t1
-> SET c1 = 6 WHERE c1 = 1;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`constraints`.`t1`, CONSTRAINT `fk` FOREIGN KEY (`c1`) REFERENCES `t1` (`c1`) ON DELETE RESTRICT ON UPDATE RESTRICT)
Now, let's try deleting row1 -
DELETE FROM t1
-> WHERE c1 = 1;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`constraints`.`t1`, CONSTRAINT `fk` FOREIGN KEY (`c1`) REFERENCES `t1` (`c1`) ON DELETE RESTRICT ON UPDATE RESTRICT)

SQL Server + Composite key or Unique Id

I am fairly new to database design, for many to many relationship, what is the differences and implications of creating a composite key and a unique id for e.g.
Country table
CountryID
CountryName
Language table
LanguageID
LangugageName
Many to Many table - using composite:
CountryID Pkey
LanguageID Pkey
OR
Using unique Id:
AutoID Pkey
CountryID
LanguageID
Composite Key :
A composite key is a combination of more than one column to identify a unique row in a table.
composite key can be a primary key .
PRIMARY KEY
The PRIMARY KEY constraint uniquely identifies each record in a database table.
so its all depend on your requirement
in first design
Many to Many Table:
Using composite:
CountryID Pkey
LanguageID Pkey
if you use this desing than CountryID and LanguageID is composite primary key.i.e here
data of the table will be
CountryId LaguageID
1 1 //valid
1 2 //valid
1 3 //valid
1 1//not valid data as its form composite primary key
and in second design
Using Unique Id:
AutoID Pkey
CountryID
LanguageID
AutoID is become primary key so this will allow data lke thsi
AutoId CountryId LaguageID
1 1 1 //valid
2 1 2 //valid
3 1 3 //valid
4 1 1 //valid as AutoID is primary key
1 2 3 // invalid as AutoID is prinary key
hope this presentation help you to understand difference
what is the differences and implications of creating a composite key and a unique id for e.g.
You'll need to create a "natural" key on {CountryID, LanguageID} to avoid duplicated connections in any case. The only question is whether you'll also need a "surrogate" key on {AutoID}?
Reasons for a surrogate key:
There are child tables that reference this junction table (and you'd like to keep their FKs slim or prevent ON CASCADE UPDATE propagation).
You are using an ORM that likes simple PKs.
Unless some of these reasons apply, use only the natural key.
BTW, under a DBMS that supports clustering, a natural key like this is usually a good candidate for a clustering key. If you cluster the table, every other index (such as the one underneath the surrogate key) has extra overhead (compared to an index in a heap-based table) since it needs to keep the copy of clustering key data and can cause a double-lookup.
See also: A column as primary key or two foreign keys as primary key.

Is alternate key indicated while creating a table but this alternate key isn't posted from any other table

The question is that if I have relation R(A,B,C,D) where A is PK and C if Alternate key for that relation, would I, while creating table based on that relation, need to indicate that C is an unique key? What I mean is:
create table R (
A A's domain,
B B's domain,
C C's domain,
D D's domain,
primary key A,
unique C
)
Do I have to specify that C is an unique key for that table even though this key isn't posted from any other table (it is just a canditate key which hasn't been selected to be a primary key?
Unique Key is a constraint, which means if you declare C as unique , then no duplicates values will be allowed for that column. If you do not specify it , it can have duplicate values, thus failed as a candidate key
If specifying it will prevent incorrect data from being inserted into the table (such that there are two rows with the same value in C), then the only reason not to do so is if it has proven to be a performance issue, and if you've demonstrated that incorrect data is prevented through some other mechanism.

restrict the values by constraint using a lookup table

I have a lookup table
Tbl_UserType_value_lookup:
UserTypeID |AllowedValue
-------------------------
1 |x
1 |y
2 |u
3 |a
(This says an user of Type 1 can enter the values of type x and y only and not of type u or a..so on)
I have another table
Tbl_Activity:
UserID |userTypeID |value
---------------------------
Now in this table how can I resrtict a user of type 1 to the values as per Tbl_UserType_value_lookup table using CHECK constraint ?
Is there any other way?
Assuming that you have a unique key on Tbl_UserType_value_lookup for UserTypeID, Allowed Value, you could have a composite foreign key on Tbl_Activity that references these columns.
(ie the combination of UserType, Value would have to exist on Tbl_UserType_value_lookup to be insertable.
There's quite a lot of discussion of this here:
Creating a composite foreign key in SQL Server 2008
I think that you can't create a dynamic CHECK constraint.
Use a foreign key to link Tbl_Activity to Tbl_UserType_value_lookup.
What you want is an application rule that can't be easily enforced in the data structure.
Tbl_Activity:
FOREIGN KEY allowed_value(userTypeID, Value)
REFERENCES Tbl_UserType_value_lookup (userTypeID, AllowedValue)
;
(If your SQL platform supports composite foreign keys, otherwise you'll have to hack some ugly triggers and/or use a surrogate key)
BTW: avoid MixedCase in table names and column names. Normally, SQL is not case-sensitive, but if your database has to be moved to a case-sensitive installation, you'll cry bitter tears. Mixing MixedCase and under_scores is considered Bad_Style (by most people).
CHECK constraints enforce domain integrity by limiting the values that are accepted by a column. They are similar to FOREIGN KEY constraints in that they control the values that are put in a column. The difference is in how they determine which values are valid: FOREIGN KEY constraints obtain the list of valid values from another table, and CHECK constraints determine the valid values from a logical expression that is not based on data in another column. For example, the range of values for a salary column can be limited by creating a CHECK constraint that allows for only data that ranges from $15,000 through $100,000. This prevents salaries from being entered beyond the regular salary range.
Use FOREIGN KEYS!
Update:
For more info, check HERE.