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

このスレッドは過去ログ倉庫に格納されています。
次スレ検索 歴削→次スレ 栞削→次スレ 過去ログメニュー
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に入れた場合に適切にエスケープしてくれるのかどうかちょっと怪しくない?
968
(7): 2023/07/15(土)18:40 ID:nkjGsW1C(1) AAS
ストアドファンクションでINSERTしたレコードを取得するにはどうすればいいでしょうか?
INSERTは下記のクエリで行っています。
RETURNS VOID になっている所を、RETURNS TABLEにしてレコードを取得したいのですが、具体的なソースコードが思いつきません。
https://ideone.com/5JPpQ4
969: 968 2023/07/15(土)18:49 ID:??? AAS
すみません。自己解決しました。
970: 2023/07/15(土)19:15 ID:??? AAS
>>968
解決した方法も書いておけよ。そうすることでQ&Aが成り立つし、次に困ったときに返信があることが期待できるようになるんだぞ。
971: 2023/07/15(土)19:58 ID:??? AAS
それが人にものを頼む態度か
972: 2023/07/15(土)21:53 ID:??? AAS
RETURNINGやろ
それ以外で自決してたら知らん
973
(1): 968 2023/07/16(日)01:02 ID:??? AAS
解決した方法は下記です。
RETURNS TABLE - RETURN QUERY です。
https://ideone.com/kgQo96

もっといい方法もあると思いますが、自分では思い付きませんでした。
974: 2023/07/16(日)01:27 ID:n5R9lLii(1/5) AAS
>>973
変数というものがわからないのか?
1-
あと 28 レスあります
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ AAサムネイル

ぬこの手 ぬこTOP 0.014s