Cassandra select on primary key without primary keys name - primary-key

Using CQL 3 I essentially want to make a statement like so....
SELECT * FROM columnFamilyName WHERE <PK>=1;
Where <PK> is a generic term for primary key.
If i have 2 tables one where the primary key name is ID, and one where it is Index, the above statement should work for both.
In a sense aerospike supports this(the primary key in aerospike simply doesnt have a name), but im not sure how to get the same generic primary key name in cassandra.

Ukemi, I'm not aware of this being possible because a Cassandra table can have a compound primary key and the first part of the primary key can also itself be a compound partition key.
E.g. in this situation:
CREATE TABLE .... PRIMARY KEY ((a, b), c, d) ..
Does <PK> refer to a, b, c or d?
Of course, if it IS possible, I'd like to know too!
Cheers,

CQL does not have a generic term for the primary key; instead you would need to provide it explicitly. Presumably an application or script which is reading from Cassandra would already have knowledge of the schema and would therefore know the key names.
However if you wanted to get the primary key column name(s) programmatically, here's one approach: use the Cassandra system tables to query the table definitions, and parse through the results to pick out the key name(s).
For example here's a simple table with a simple primary key (partition key):
cqlsh:key1> create table table1 (a int, b int, c int, primary key (a));
cqlsh:key1> select column_name,component_index,type from system.schema_columns
... where keyspace_name='key1' and columnfamily_name='table1';
column_name | component_index | type
-------------+-----------------+---------------
a | null | partition_key
b | 0 | regular
c | 0 | regular
And here's a slightly more complicated primary key like #reggoodwin suggested:
cqlsh:key1> create table table2 (a int, b int, c int, d int, e int,
... primary key ((a, b), c, d));
cqlsh:key1> select column_name,component_index,type from system.schema_columns
... where keyspace_name='key1' and columnfamily_name='table1';
column_name | component_index | type
-------------+-----------------+----------------
a | 0 | partition_key
b | 1 | partition_key
c | 0 | clustering_key
d | 1 | clustering_key
e | 2 | regular
For more information, check out the docs page on Querying a system table.

Related

Primary key of a simple 1:1-mapping table with NULL values?

This feels like a very basic question, but I really don't see the obvious answer at the moment.
I have a simple table that maps object ids between two namespaces:
|---------------------|------------------|
| id_in_ns1 | id_in_ns2 |
|---------------------|------------------|
| 1 | 5 |
|---------------------|------------------|
| 2 | 17 |
|---------------------|------------------|
| 3 | NULL |
|---------------------|------------------|
| NULL | 1 |
|---------------------|------------------|
The mapping is basically 1:1, but as you can see, some objects from namespace 1 do not exist in namespace 2, and vice versa, so that there are NULL values in the table.
So, what would be the primary key of this table? As a PK cannot be NULL, I can neither use (id_in_ns1) nor (id_in_ns2) nor the composite.
The only idea I have is to replace NULL by a definite value, say -1, and to use (id_in_ns1, id_in_ns2)as PK. However, this feels not only hackish but also "unnormal" because the non-NULL (or non--1)) value alone is already sufficient to uniquely identify an object.
Only add entries that have a valid id on both sides. This will effectively get rid of all NULL values, allowing you to specify a proper composite key on (id_in_ns1, id_in_ns2).
Ultimately, those are the values that allow you to identify a single row and you will not lose relevant information - a SELECT id_in_ns2 FROM mapping_table WHERE id_in_ns1 = x will return NULL either way, whether there is a (x, NULL) row or not.
If you insist on keeping those NULLs you could add another column with an artificial (auto incrementing) primary key, but that feels as hacky as using -1.
Use a synthetic primary key and use unique constraints for the rest:
create table mapping (
mappingId int auto_increment primary key, -- or whatever for your database
id_in_ns1 int references ns1(id),
id_in_ns2 int references ns2(id),
unique (id_in_ns1),
unique (id_in_ns2)
);
Just one caveat: some databases only allow one NULL value for UNIQUE constraints. You might need to use a filtered unique index instead (or some other mechanism) for this construct.

How to update rows of two tables that have foreign key restrictions

I have two tables: one is foreign reference table lets say table a and other one is the data table lets say table b.
Now, when I need to change the data in table b, but I get restricted by table a.
How can I change "rid" in both tables without getting this message?
"ERROR: insert or update on table "table a" violates foreign key
constraint "fk_boo_kid" SQL state: 23503
Detail: Key (kid)=(110) is not present in table "table b".
Example query to update both tables:
UPDATE table b table a SET rid = 110 WHERE rid =1
table b
+-----+-------+-------+
| rid | ride | qunta |
+-----+-------+-------+
| 1 | car | 1 |
| 2 | bike | 1 |
+-----+-------+-------+
table a
+-----+-----+------------+
| kid | rid | date |
+-----+-----+------------+
| 1 | 1 | 20-12-2015 |
| 2 | 2 | 20-12-2015 |
+-----+-----+------------+
In Postgres you can use a writeable CTE to update both tables in a single statement.
Assuming this table setup:
create table a (rid integer primary key, ride text, qunta integer);
create table b (kid integer primary key, rid integer references a, date date);
The CTE would be:
with new_a as (
update a
set rid = 110
where rid = 1
)
update b
set rid = 110
where rid = 1;
As (non-deferrable) foreign keys are evaluated on statement level and both the primary and foreign key are changed in the same statement, this works.
SQLFiddle: http://sqlfiddle.com/#!15/db6d1/1
you can not update/delete primary key in table B, because the primary key is used in table A.
you can delete primary key in table B, IF >>
you must delete the row in table A which is used primary key table B.
you can delete the row in table B
you have to change both manual
SET session_replication_role = 'replica';
UPDATE table a SET rid=110 WHERE rid=1 ;
UPDATE table b SET rid=110 WHERE rid=1 ;
SET session_replication_role = 'origin';
This is too long for a comment.
You should really explain why you want to change ids into something else. Primary keys really should be considered immutable, so they identify rows both within a table and over time.
If you do need to change them for some reason, then define proper foreign key constraints for the tables in question. Then define the foreign keys to be on update cascade. This will "cascade" changes to all affected changes when a primary key changes.

Composition in database

Hi this article author wrote:
An IssueManagement can NOT exist without an Issue and as such seems to me well suited to using
So now why the foreign key from Issue table is not part of primary key in IssueManagement table?
This is because IssueMagement already have an autonumeric ID as primary key to make sure each row is unique.
Let me show you an example, but instead of number for ID I will use letters.
Isues Issue Magament
ID | IDM ID
A | X A
B | Y B
C | Z A
You only IDM to identify each Issue Magamentrow.

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)

how to keep combination of cells unique

i have table A and table B. I have a bridge table called tableC
in table C i have:
ID
tableA_ID
tableB_ID
ID is the primary key.
i also want to enforce the combination of tableA_ID and tableB_ID to be unique so there are no duplicate records.
how do i enforce this?
create unique index myIdx on tableC(tableA_ID, tableB_ID)
or whatever the syntax for your particular database system is.
Make the PRIMARY KEY tableA_ID and tableB_ID, EXCLUDING ID
lets say we have a table TABLEA with values
tableAID
1
2
3
and table TABLEB with values
tableBID
4
5
6
making the primary key (ID, tableA_ID, tableB_ID) will not work eg.
ID | tableAID | tableBID
1 | 1 | 4
2 | 1 | 4
will work fine with the above pk, but you need PRIMARY KEY (tableA_ID, tableB_ID)
Drop the ID column then make the other two columns the primary key and their uniqueness will be enforced by the database server.
It's not really necessary to have the ID column - even though it serves as a handy way of referencing a particular record - as the uniqueness of the other two columns will mean that they are sufficient to reference a particular record.
You may also want to put an index on this table, that includes bothe columns, to make access faster.