[過去ログ] PostgreSQL Part.11©2ch.net (1002レス)
1-

このスレッドは過去ログ倉庫に格納されています。
次スレ検索 歴削→次スレ 栞削→次スレ 過去ログメニュー
948: 2022/12/09(金)12:22 ID:??? AAS
そんなのプログラムの作りによるんじゃないの
DBに依存しまくってると苦労する
949: 2023/01/15(日)23:52 ID:SdlFKp5i(1) AAS
ブチクシは悩み続けて3年
950: 2023/01/19(木)07:06 ID:??? AAS
ちんちん!シュッ!シュッ!シュッ!
951: 2023/01/19(木)22:38 ID:jlE8WkqW(1) AAS
>>946
メインフレームのファイルのようなものじゃなくて、データファイルの内部は頻繁にデータの位置を変えている。

そんな古風な仕組みではない。
952: 2023/01/20(金)13:33 ID:??? AAS
カラム情報としてポインタになってるだけだね。適当
953: 2023/03/11(土)05:08 ID:aB1pzwA3(1) AAS
外部キー制約を一時的に変更するにはどうすればいいでしょうか?
通常は、ON UPDATE RESTRICT で、一時的に ON UPDATE CASCADE にしてクエリ実行後に RESTRICT に戻すにはどうすればいいのでしょうか?
ADD CONSTRAINT と DROP CONSTRAINT の方法は分かるのですが・・・
954: 2023/03/11(土)16:56 ID:??? AAS
ALTER TABLEのALTER CONSTRAINTではできないのでDROP/ADDする

ALTER TABLE <table_name>
DROP CONSTRAINT <fk_name
ADD CONSTRAINT <fk_name> FOREGIN KEY … ON UPDATE CASCADE;
955: 2023/04/22(土)19:34 ID:g9MOSe1r(1) AAS
物理外部キーを作るくらいなら、論理外部キーとしておいた方が楽。

ガチガチにしておいても、エラーハンドリングの実装がなければ意味がない。
956: 2023/06/25(日)23:14 ID:??? AAS
update on conflictを使いまくってるとシーケンス値が上がりまくって、primary keyのidの値が飛びまくるんだけど
気にしたら負けかな。
もちろん綺麗に1 2 3とならない事は認識してるけど、1 1235 5493 29849 みたいに膨大な数飛びまくると…。

99%がupdateの場合なんだけど、update returningして件だったらinsertにした方がいいのかな
その場合ロックとか考えなきゃいけないのが大変なんだけど、もう避けられないのかな
957
(1): 2023/06/26(月)18:19 ID:??? AAS
insert on conflict do update(いわゆるupsert)のことだよね?
conflictの条件をprimary keyにできないならPKのシーケンスが飛びまくるのはしょうがないと思う
ただ99%がupdateならupdateしてからinsertのほうが性能は良くなるような気がする

ロックを考えなきゃいけないというのはよくわからない
今も同じじゃない?
958
(1): 2023/06/26(月)20:59 ID:??? AAS
言いたいのはロックじゃなくてトランザクションじゃないかな
959: 2023/06/26(月)22:46 ID:??? AAS
>>957-958
ありがとうございます。
on conflict do updateであれば、トランザクション貼らずともコマンドを実行するだけで確実にinsertかupdateが確定で成功するけど
update → insertだと両方updateが0件になって両方insertしようとして片方がエラー という事が起きるかなと認識していました
960: 2023/06/27(火)01:12 ID:??? AAS
update → insert on conflict do updateをトランザクションでくくれば今と同じなんじゃないかな

ただREAD COMMITEDならlost updateが発生してるだろうから
本当にそれが望ましいのかよく考えたほうがいいと思う
961: 2023/07/02(日)05:52 ID:??? AAS
insert into 〜 on conflict do updateでシーケンス値が増えるのが我慢できなくて
insert into 〜 on conflict do update相当の処理をトランザクションで書いているのですが
これって最終的にテーブルに対してACCESS exclusiveロック(selectすら妨害する最強ロック)をかける事が必須だったりしますか?

上記のクエリと同じ処理を行いたい場合、以下の処理を行う必要があると思います
・select文で該当の行が既にあるかをチェック
・select文の結果を見て、該当の行があればupdate
・select文の結果を見て、該当の行が無ければinsert

トランザクション1と2が両方同じタイミングでselect文を発行して、どっちもresultが0だった場合、どっちもinsertをしようとしてしまう。
だからどちらか片方のselect文は、他のinsertが終わるまで待ってから行って、result 1を取得する必要がある。

最初は行ロックでいいかな?と思ったのですが、最初にselectをした段階で対象の行は「存在しない」ので行ロックがかけれません。
省3
962
(2): 2023/07/02(日)06:05 ID:??? AAS
違った。
SHARE UPDATE exclusiveモードを使えばよかったのか
失礼しました
963: 2023/07/02(日)06:12 ID:??? AAS

964: 962 2023/07/02(日)22:36 ID:??? AAS
同じ話題を引っ張り続けて申し訳ないけど、自分でinsert〜on conflict do update(upsert)相当の事をするのが面倒すぎて、趣味ですら面倒で手が止まる。
仕事じゃ絶対提案出来ないな(ダルすぎて)
自分の場合は実際には1000件単位のデータをupsertしてるんだけど、この数だと1件づつselect→(update or insert)は遅すぎる。
select文で1000件のデータのユニークキーに対して長いwhere 文を作る。
( SELECT id,key FROM tbl WHERE key in ( $1 , $2 , $3 .... , $1000) )

select文の結果を入れたい1000件単位のデータと比較して、1件づつinsertするかupdateするかを判定する
insert、updateも1件づつやるとトランザクションしても遅いから1リクエストで済むように動的にクエリ文を作る。
( INSERT INTO tbl (key) VALUES ($1),($2)... )
( UPDATE tbl SET key=c.key FROM( VALUES ( ($1,$2),($3,$4),...) AS c(id,key) WHERE tbl.id=c.id )

そしてupsertから加えた機能で、含まれてないデータをDELETEもするようにしてるからさらにクエリ文が増える。
省3
965: 2023/07/03(月)00:19 ID:??? AAS
その1000件とかの入力データに同じユニークキーを対象としたデータがあった場合にどうしたいの?
何か累積値や合計値を計算してて必ずカウントアップしていかないといけないとか
入力データ内の順序で後のデータを正として先のデータは捨てられてもいいとか

>>962
>SHARE UPDATE exclusiveモードを使えばよかったのか
これだとテーブルロックになるので1つのトランザクションが終了するまで次のトランザクションは待つことになる
これで十分なユースケースならそもそも同じキーに対して同時にinsertが実行される心配しなくてもいいよね?分離レベルをSerializableにすれば該当キーがロックされるだけで済むはず
966: 2023/07/03(月)03:52 ID:??? AAS
ごめんなさい、SQLクエリについてはSHARE UPDATE exclusiveのロックを取得する。で何の問題もありません。

自分が今悩んでいるのは、SQL文が動的になって書くのが大変という事です。
1000件あるデータ以下のような1回のinsert文で全ての値を登録するなどの事をしています。
insert into tbl (key1,key2,key3) values(1,2,3),(4,5,6),(7,8,9);

nodejsの場合、プログラムの中からSQLを実行する時は以下のような書き方をするのですが
query(`insert into tbl(key)values($1)`,[1]);

これが可変になると、以下のような書き方になってものすごく読みにくく感じます。実際はパラメーター複数あってさらに複雑ですし。
query(`insert into tbl(key)values ${insertDatas.map((v,i)=>`($${i+1})`).join(",")}`,insertDatas);
もちろんプログラムとしては全く難しくないのですが、素直に言ってダルい。$が連続しているのも読みにくさが増す理由になってる。

なので、こういう場合はO/Rマッパーというものを使えば
省3
967: 2023/07/03(月)18:43 ID:??? AAS
ORMじゃなくてもbulk insert用のSQLを生成/フォーマットする機能のあるライブラリを選べばいいよ

>query(`insert into tbl(key)values ${insertDatas.map((v,i)=>`($${i+1})`).join(",")}`,insertDatas);
string interpolationに入れた場合に適切にエスケープしてくれるのかどうかちょっと怪しくない?
1-
あと 35 レスあります
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ AAサムネイル

ぬこの手 ぬこTOP 0.175s*