I am currently working on a set of queries to pull data from a SQL table and then loop to pull any entries from other tables that are referenced in the first table through foreign keys.
aka if Table A column A can only have values that appear in Table B's primary key, I want to pull all rows of Table B referenced in my extract from Table A.
To do this in the past, I would have written a query that looks at information_schema.table_constraints and matched it against the key columns; Something like the suggested query in this article. However, when I pull the information from the table_constraints table in my current database, I get back an empty response; I get the table headers, but no rows. This is despite the fact that I know that there are many constraints, particularly foreign-key constraints, in the Postgresql database that I am using. The query giving me the empty response is as simple as possible, shown below:
SELECT * FROM information_schema.table_constraints
Is there somewhere else that I should be referencing to get the foreign key constraint information? How else can I find the foreign key constraints on a table?
EDIT: I am having a touch more luck finding things through pg_catalog; The data at least seems to exist in there. However, it is all abstracted as numerical IDs, and I am having a little trouble linking enough together to get to the actual column names and other key data.
In the information_schema views you can only see objects for which you have permissions.
You are planning to do a join, not lots of little queries by primary key, right?
Related
have a table called RoundTable
It has the following columns
RoundName
RoundDescription
RoundType
RoundLogo
Now the RoundType will be having values like "Team", "Individual", "Quiz"
is it necessary to have a one more table called "RoundTypes" with columns
TypeID
RoundType
and remove the RoundType from the rounds table and have a column "TypeID" which has a foreign key to this RoundType table?
Some say that if you have the RoundType in same table it is like hard-coding as there will be lot of round types in future.
is it like if there are going to be only 2-3 round types, i need not have foreign key??
Is it necessary? Obviously not. SQL works fine either way. In a properly defined database, you would do one of two things for RoundType:
Have a lookup table
Have a constraint that checks that values are within an agreed upon set (and I would put enums into this category)
If you have a lookup table, I would advocate having an auto-incremented id (called RoundTypeId) for it. Remember, that in a larger database, such a table would often have more than two columns:
CreatedAt -- when it was created
CreatedBy -- who created it
CreatedOn -- where it was created (important for distributed systems)
Long name
In a more advanced system, you might also need to internationalize the system -- that is, make it work for multiple languages. Then you would be looking up the actual string value in other tables.
is it like if there are going to be only 2-3 round types, i need not
have foreign key??
Usually it's just the opposite: If you have a different value for most of the records (like in a "lastName" column) you won't use a lookup table.
If, however, you know that you will have a limited set of allowed/possible values, a lookup table referenced via a foreign key is probably the better solution.
Maybe read up on "database normalization", starting perhaps # Wikipedia.
Actually you need to have separate table if you have following association between entities,
One to many
Many to many
because of virtue of these association simple DBMS becomes **R**DBMS ( Relation .)
Now ask simple question,
Whether my single record in round table have multiple roundTypes?
If so.. Make a new table and have foreign key in ROUNDTable.
Otherwise no.
yeah I think you should normalize it. Because if you will not do so then definitely you have to enter the round types (value) again and again for each record which is not good practice at all in case if you have large data. so i will suggest you to make another table
however later on you can make a view to get the desired result as fallow
create view vw_anyname
as
select RoundName, RoundDescription , RoundLogo, RoundType from roundtable join tblroundtype
on roundtable.TypeID = tblroundtype .typeid
select * from vw_anyname
I'm looking for a way to set up a one to many relationship between 2 tables. The table structures is explained below but I've tried to leave everything off that has nothing to do with the problem.
Table objects has 1 column called uuid.
Table contents has 3 columns called content, object_uuid and timestamp.
The basic idea is to insert a row into objects and get a new uuid from the database. This uuid is then used stored for every row in contents to associate contents with objects.
Now I'm trying to use the database to enforce that:
Each row in contents references a row in objects (a foreign key should do)
No row in objects exists without at least a row in contents
These constraints should be enforced on commit of transactions.
Ordinary triggers can't help probably because when a row in the objects table is written, there can't be a row in contents yet. Postgres does have so called constraint triggers that can be deferred until the end of the transaction. It would be possible to use those but they seem to be some sort of internal construct not intended for everyday use.
Ideas or solutions should be standard SQL (preferred) or work with Postgres (version does not matter). Thanks for any input.
Your main problem is that other than foreign key constraints; no constraint can reference another table.
Your best bet is to denormalize this a little and have a column on object containing the count of contents that reference it. You can create a trigger to keep this up to date.
contents_count INTEGER NOT NULL DEFAULT 0
This won't be as unbreakable unless you put some user security over who can update this column. But if you keep it up to date with a trigger and all you're looking to avoid is accidental corruption, this should be sufficient.
EDIT: As per the comment, CHECK constraints are not deferrable. This solution would raise an error if all the contents are removed even if the intention is to add more in the same transaction.
Maybe what you want to do is normalize a little bit more. You need a third table, that references elements of the other tables. Table objects should have its own uuid and table contents sholud have also its own uuid and no reference to the table objects. The third table should have only the references to the other two tables, but the primary key is the combination of both references.
so for example you have an uuid of the table objects and you want all the contents of that uuid, assuming that the third table has as columns object_uuid and content_uuid, and the table contents has its own serial column named uuid, your query should be like this:
SELECT * FROM thirdtable,contents
WHERE thirdtable.content_uuid = contents.uuid AND thirdtable.object_uuid=34;
Then you can use an on insert trigger on every table
CREATE TRIGGER my_insert_trigger AFTER INSERT OR UPDATE ON contents
FOR EACH ROW EXECUTE PROCEDURE my_check_function();
and then in function my_check_function() delete every row in objects that is not present in the third table. Somebody else answered first while I was answering, if you guys like my solution I could help you to make the my_check_function() function.
I have a table with one column source_id whose value should be the primary key of another table, though which table it is will vary from record to record. Every record must have a value for source_table that specifies the table for the source record, and a value for source_id that specifies the row in the source table.
Is there any way to accomplish this to take advantage of the DB's foreign key constraints and validation? Or will I have to move my validation logic into the application layer? Alternately, is there another design that will just let me avoid this problem?
Foreign key constraints can only reference one target table. "Conditional" foreign keys which reference a different target table based on some other field are not available in SQL. As #OMG Ponies noted in a comment below, you can have more than one foreign key on the same column, referencing more than one table, but that would mean the value of that column will have to exist in all the referenced tables. I guess this is not what you are after.
For a few possible solutions, I suggest checking out #Bill Karwin's answer to this question:
Possible to do a MySQL foreign key to one of two possible tables?
I like the "supertable" approach in general. You may also want to check out this post for another example:
MySQL - Conditional Foreign Key Constraints
I think previous answers do answer the first part of the question well. However link recommended by Daniel provides a solution only for the case when the number of referenced "source" tables is reasonably small. And the solution will not scale easily if you decide to increase the number of "source" tables.
To recommend a better strategy it would be nice to have a little more details on what the task is and if the "source" tables have anything in common that would allow to combine them.
In current structure (as far as I can infer from the question) I would reverse the relationship:
I would create a table (let's call it AllSources) that would work as a repository of all available sources with columns source_id and source_table. Both included in the primary key.
I would create foreign keys from each "source" table referencing AllSources table so that they could have only sources already registered in it.
Then I would create the table you mentioned in your question with foreign key referencing the AllSources table (not separate "source" tables).
Drawback: you will have to manage AllSources and "source" tables together ensuring that if you create a record in AllSources, you also create a corresponding record in proper "source" table, which in reality is not that hard.
So I'm working on just a learning project to expose myself to doing some things I do not get to do at work. I'm just making a simple bug and case tracking app (I know there are a million this is just to work with some tools I don't get to). So I was designing my database and realized I've never actually used Foreign Keys before in any of my projects, I've used them before but never actually setting up a column as a FK. So I've designed my database as follows, which I think is close to correct (at least for the initial layout).
Database Image http://drop.io/download/public/uurp1vxej0abpwu7jsee/895663dedff577359b900cda1726f115b24be90c/Asset/28368622/v3/large_thumbnail
However When I try to add the FK's to the linking Tables I get an error saying, "The tables present in the relationship must have the same number of columns". I'm doing this by in SQLSMS by going to the Keys 'folder' and adding a FK. Is there something that I am doing wrong here, I don't understand why the tables would have to have the same number of columns for me to add a FK relationship between the tables?
When defining a foreign key relationship there are four things you need to specify:
The referring table (foreign key table)
The columns from the referring table that will form the foreign key.
The referred table (primary key table)
The columns from the referred table that form the key.
I'm guessing that you have selected one of the above incorrectly - probably you have forgotten that you need to state the column involved in the relationship twice - once for each table.
Here's a screenshot of how it should look - note that the column is specified twice. In my example the columns have slightly different names to demonstrate that they don't always need to have the same name, but in your case the column names will be the same.
I am working on a legacy database. I am not able to change the schema :( in a couple of tables the primary key uses multiple columns.
In the app I read the data in each row into a table the user then updates the data and I write the data back into the table.
Currently I concatenate the various PK columns and store them as a unique id for when I put the data back into the table.
Now I was wondering if there is a more efficient way to do that. Coming from a mySQL background I am not aware of any but thought SQL Server 2005 may have a function
SELECT PRIMARYKEY() as pk, ... FROM table WHERE ...
the above would select the key that the database engine uses as the primary key for the given record
I searched and couldn't find anything. Its probably just me being fussy but I don't like the concatenation trick.
DC
In SQL Server, there is no equivalent of PRIMARYKEY() that I would be aware of, really. You can consult the system catalog views to find out which columns make up the primary key, but you can't just simply select the primary key value(s) with a function call.
I would agree with StarShip3000 - what do you concatenate your PK values for? While I don't think a compound primary key made up of several columns is necessarily a very good idea, if it's a legacy system and you can't change it, I wouldn't bother concatenating the PK values on read, and then having to split them apart again when you write your data back. Just leave the structure as it is - compound keys aren't generally recommended, but they are indeed supported, no problem.
"Currently I concatenate the various PK columns and store them as a unique id for when I put the data back into the table."
Can't you just store the pk as two columns in the target table and use that to join back to the two columns on the source table?
What benefit is concatenating giving you here?