[TIL] # 30 Django CRUD (2)


select relatedとprefetch relatedに重点を置く
他の内容を整理したいです.
とても主観的で、私の考えがたくさん含まれています.



users, posts, comments
テーブルが3つあります

Select_related


前のブログでSelect relatedがどのように機能しているかを見ることができます
私は理解したと思っていたので、また勉強しました.
私が勉強を再開したときに感じたのは

私が知っているのとは違いますか?かつて


まずSelect relatedを検索し、最初に見たのはJOINのはずです
そして正しい事実

私が理解しているselect related


  • JOINを使用して関連クエリーを取得する場合に使用

  • ドラムはselect relatedを使わず、JOINが必要なら自動使用

  • ここでqueryを追加インポートする場合はprefetch relatedを使用します.

  • 正参照なら、持ってきてもいいです.

  • 非常に複雑なORMではRIGTH OUTER JOINが発生する可能性があります.
    一般的にRIGTH OUTER JOINはあまり発生しません
  • 正の参照
    Postのuser idを使用して複数のpostを作成できます.
    ここではuser idのpostを使用してuserのカラム値を参照します.
    「≪マルチ|Multi|emdw≫」表で「≪日|Days|emdw≫」表を参照します.

    Post.objects.select_related("user").filter(id = 1)
    SELECT `posts`.`id`, `posts`.`content`, `posts`.`user_id`, `posts`.`created`, `posts`.`updated`, `posts`.`photo`, `users`.`id`, `users`.`email`, `users`.`password` 
    FROM `posts` INNER JOIN `users` 
    ON (`posts`.`user_id` = `users`.`id`)
    例はあまりよくありませんが.
    コードのみを参照する場合は、postでFKを接続するuserを参照してください.
    postのidは1人のクエリーをもたらします
    こんな風に流れて

    select relatedを使用せずにJOINを使用する場合

    Post.objects.filter(id = 1, comment__content = "endendend")
    SELECT `posts`.`id`, `posts`.`content`, `posts`.`user_id`, `posts`.`created`, `posts`.`updated`, `posts`.`photo` 
    FROM `posts` INNER JOIN `comments` 
    ON (`posts`.`id` = `comments`.`post_id`) 
    WHERE (`comments`.`content` = endendend AND `posts`.`id` = 1)
    上記の場合、select relatedは使用されません.
    長期的には、必要に応じてJOINが使用されていることが確認できます.
    張高は自分で判断して使うが.
    残念なことに私が書いたのは正しいですか?
    時々考えがある

    select relatedの使用


    postに文章を書いたユーザーの電子メールを持ってきたいなら
    posts = Post.objects.select_related("user")
    for post in posts:
    	post.user.email
        
    >>>kim@naver.com
    >>>lee@gmail.com
    >>>kim@naver.com
    >>>jung@naver.com
    >>>kim@gmail.com
    もちろんselect relatedを使わなくても
    posts = Post.objects.all()
    for post in posts:
    	post.user.email
    この方法で持ってきてもいいですが.
    select relatedを使うことでJOINを使って持ってきました
    もっとはっきり見える
    こうしてみるとselect relatedはINNERJOINを使う場合のみ
    ではOUTER JOINはどのように表現しますか?
    OUTER JOINの場合、最初にSQL文として扱うと、NULL値を含む状態として出力されます
    JOINのSQL文について
    https://velog.io/@ddalkigum/TIL-28-SQL%EB%AC%B8-2
    だからOUTER JOINが欲しければ.
    null=TrueのFKが含まれている場合は、
    しかし,長い目で見れば,ライティングコードの特性上,RIGHT OUTER JOINは不可能である.
    親nttは常に左側にあるため
    親とは言い難いけど、、、うーん...主人.親ではなく、主人で、理解すればいいです.
    文章の持ち主

    逆参照の場合


    postからuserまで、postからcommentまでではなく、逆参照はselectに関連付けられません.
    post = Post.objects.select_related("comment_set")

    張高はとても親切に場の誤差を出した.

    Prefetch_related


    この友達は本当に理解できない.
    どこで使うかから、なぜ使うのか.
    使用するたびに異なるクエリー文が出力される理由
    张高会看做...答えだろう.

    私の理解するプリフェッチrelated


  • さまざまな状況で使用可能

  • 1対の複数の関係で逆参照を行う場合に使用できます.

  • 上記のselect relatedの後、追加のクエリーが発生した場合に使用できます.

  • 張高はとても親切で,私にははっきりしない.
  • むずかしいところ

    posts = Post.objects.select_related("user").prefetch_related("comment_set")
    SELECT `posts`.`id`, `posts`.`content`, `posts`.`user_id`, `posts`.`created`, `posts`.`updated`, `posts`.`photo`, `users`.`id`, `users`.`email`, `users`.`password` 
    FROM `posts` INNER JOIN `users` 
    ON (`posts`.`user_id` = `users`.`id`)
    何だと思いますかprefetch relatedを使いました
    select relatedを使用する場合、クエリー文と同じですか?
    本当に...難解
    コメントを明確に引用しました(もちろん、コメントに関する内容は使用していませんが)
    結果を持ってきたいのですが、なぜクエリ文が同じなのでしょうか.
    思い切れない
    post = Post.objects.prefetch_related("comment_set").filter(comment__id = 1)
    SELECT `posts`.`id`, `posts`.`content`, `posts`.`user_id`, `posts`.`created`, `posts`.`updated`, `posts`.`photo` 
    FROM `posts` INNER JOIN `comments` 
    ON (`posts`.`id` = `comments`.`post_id`) 
    WHERE `comments`.`id` = 1
    このように逆参照を行うと、commentのidがpostをもたらします.
    prefetch relatedもselect relatedのように使う必要はありません
    ドラムで処理されていますが、上記のように
    私の意図を理解させたほうがいいと思います.

    プリフェッチを無効にする

    post = Post.objects.filter(comment__id = 1)
    SELECT `posts`.`id`, `posts`.`content`, `posts`.`user_id`, `posts`.`created`, `posts`.`updated`, `posts`.`photo` 
    FROM `posts` INNER JOIN `comments` 
    ON (`posts`.`id` = `comments`.`post_id`) 
    WHERE `comments`.`id` = 1
    私たちから見れば非常に簡単なコードです.
    倉庫内部ではINNERJOINを使用していると判断できる
    post = Post.objects.filter(comment__id = 1).prefetch_related("comment_set")
    SELECT `posts`.`id`, `posts`.`content`, `posts`.`user_id`, `posts`.`created`, `posts`.`updated`, `posts`.`photo` 
    FROM `posts` INNER JOIN `comments` 
    ON (`posts`.`id` = `comments`.`post_id`) 
    WHERE `comments`.`id` = 1
    完全に同じ内容のクエリー文は、複数の表現が可能です.
    この部分もちょっと驚きましたが、、、、張高が見てやるのは知っています.
    あ….これも同じだと思います.
    user = User.objects.prefetch_related("like_set").filter(id = 1)
    likes = user[0].like_set.all()
    # user의 쿼리문 
    
    SELECT `likes`.`id`, `likes`.`user_id`, `likes`.`post_id` 
    FROM `likes` 
    WHERE `likes`.`user_id` = 1
    
    # likes를 가지고 오는데 까지의 쿼리문 
    
    SELECT `users`.`id`, `users`.`email`, `users`.`password` 
    FROM `users` 
    WHERE `users`.`id` = 1
    では、関連するプレイヤーを見つけるために、Dadatフィールドで逆参照します.
    ライクをクリックしたプレイヤーたち
    見ればわかるように、クエリ文は逆に短くなっています
    どんなに長いコードを入れても、query文を判断して発行します.
    こうやって検索を見ると、私は効果的に編成できなかったんですよね...とも思う.
    他所から、持ってきた方法で使うと、もっと効率的になります.
    万感こもごも至る
    より効率的なコードを書きたいのですが
    多くのコードを見て、体験して、どのように書くのがもっと効率的かを考えてみましょう.
    これは私のとても主観的な文章です...
    間違ったところがあればメッセージをお願いします😁