Re: Foreign Key 'walker'?

Поиск
Список
Период
Сортировка
От Erwin Moller
Тема Re: Foreign Key 'walker'?
Дата
Msg-id 49242AC2.9010201@darwine.nl
обсуждение исходный текст
Ответ на Re: Foreign Key 'walker'?  (Craig Ringer <craig@postnewspapers.com.au>)
Ответы Re: Foreign Key 'walker'?  (Erwin Moller <erwin@darwine.nl>)
Список pgsql-general
Craig Ringer schreef:
> Erwin Moller wrote:
>
>> No, that is not the kind of chicken I was talking about. ;-)
>> My chicken is more along these lines:
>> I often have some tables to which everything is related (eg tblcourse
>> that contains everything belonging to a certain course).
>> I don't want to make a single simple mistake that if I accidentally
>> delete an entry there, I lose all underlying data via the CASCADE.
>
> OK, so the idea is to prevent DELETEs of records with existing
> relationships, except when invoked via some sort of script or wrapper
> that says, essentially, "Yes, I really do mean delete this record and
> all its related records, I'm not just accidentally issuing a DELETE".
>
> Personally, if I had to do this I'd do this with a PL/PgSQL function
> that dug through pg_catalog or INFORMATION_SCHEMA to do a depth-first
> search and delete of the related records. Frankly, though, it sounds
> horrible, and if you run into a relationship loop you're in a real
> mess. At least the latter problem can't bite you unless you use
> DEFERRED constraints.
Hi Craig,

Thanks for your reply.

For clearity's sake: If I want to delete a record that is refered to, I
always simply first delete the 'lower' records that fit my criteria,
then the 'higher'.
So I often end up with a series of deletes, which when executed in that
right order, do the same as a CASCADE would do on the 'higher' record.

Reason is simply I rather hit a FK constraint than a cascading delete on
mistake.
(I am programming against postgresql in almost all my projects, thus
this mistake just happens from time to time.)

So, that is the way I prefer doing it: It keeps me sharp because I force
myself to always understand each relation in every table that in in 'the
chain'.
So I am NOT looking for help on writing such a wrapper/script/function
to do this, because I prefer doing it myself.

I do not mind making a few deletes (allthough they get more and more
complex if you have more levels).
I asked this weird question because it would come in handy if I could
get the list of tables that are connected via FK to my table in question.

Is this clear? Maybe I have a weird way of programming. ;-)

>
>> No problem at all.
>> I totally agree with you.
>> I only have this fear I screw up (not Postgresql) if I use CASCADE
>> and accidentally delete a 'high' record in the chain.
>
> To me, that sounds like you might have some of your relationships
> backwards. Generally I wouldn't want to set an ON DELETE CASCADE
> relationship on a parent record (not does it usually make any sense) ;
> rather, the relationship on the child record will have ON DELETE
> CASCADE set so the child will be deleted if the parent is. Deleting a
> child record should only delete the child record, never cascade up to
> a parent.
I must have written very poorly, since that is NOT what I mean.
(I am not a native english speaker, so indulge me please).

I totally agree with the statement that a DELETE should NEVER cascade up
to the parent record, and I'll never design a database like that.

Possibly my poor understanding of CASCADE is the root of this confusion.
(I wrote already I never use it).
I thought that is I define a field in a table with 'ON DELETE CASCADE'
that means that ANY record in other tables that have a FK constraint on
this parenttable are also deleted.
And the same for child-child-tables, etc.

Do I have that right?

>
> The child record is useless and meaningless without the parent, so
> this is appropriate.
>
> For a practical example in a course/student management tool: If you
> delete a `student', and the student has `student_course' (an m:n
> mapping table) entries referencing `course', you would not expect the
> course to be deleted, only the student<->course relationship and the
> student. If the course was deleted explicitly by the user, you'd
> expect the student_course relationship to restrict the deletion if
> students were still listed as taking the course. So, the natural
> definition would be:
>
> CREATE TABLE student_course (
>    student_id INTEGER REFERENCES student(student_id) ON DELETE CASCADE,
>    course_id INTEGER REFERENCES course(course_id) ON DELETE NO ACTION,
>    PRIMARY KEY(student_id, course_id)
> );
>
> ... which is pretty close to what you end up with if you just bang out
> the obvious structure for the relationship.
Well, that is excactly the way I work too. So we agree here.

To stick to this example: I was describing the situation I accidently
DELETED course_id in table course.
I don't want that that deletion cascades though the whole database and
deletes all related rows.

But maybe I misinterpret the way CASCADE works (see my explanation above).

Regards,
Erwin Moller

>
> There are odd cases where those relationships end up being reversed
> (or at least bidirectional), and in those cases I do tend to avoid ON
> DELETE CASCADE, instead providing functions, triggers or rules to
> clean up appropriately.
>
> --
> Craig Ringer
>
>
>


В списке pgsql-general по дате отправления:

Предыдущее
От: Sam Mason
Дата:
Сообщение: Re: Any risks in using FUNCTIONs (stored procedures) instead of raw sql queries?
Следующее
От: Scara Maccai
Дата:
Сообщение: return MAX and when it happened