Related to #3510, #4203
Working on https://github.com/syuilo/misskey/tree/pg
大変そう。手伝えることがあったら言ってください。
ありがとうございます!
一部で行っている複雑なクエリをPostgreSQLで実現できるかなど分からない部分もありますが頑張ります
ちなみに何を使うとかいう具体的な方針は決まってたりしますか?
PostgreSQLの具体的なバージョンはまだ未定ですがORMはtypeormの予定です
pgブランチ作りました。
まずモデル定義(src/models)をtypeormを使用したものに書き換えていく必要があります。例はここら辺に
時間のある方はこの作業に参加していただけると助かります
外部キー制約って配列には適用できない...?
例えば投稿の添付された複数のファイルを表すfileIdsとか
noteFileAttachment といった別のテーブル作るしかないか
renoteCount とか repliesCount とか reactionCounts とか保存すべき?
これらのカラムはすべて非正規化されてるようなもので、これらが無くても理論的にはその投稿のRenote数や返信数やリアクション数は取得できる
とりあえず無くしといてパフォーマンス上の問題があるようなら非正規化でも良いかもしれないけど後から設計を変えるのもそれはそれで面倒
visibleUserIds も外部キーの配列だけど、さすがにこれのためだけにテーブル作るのはなんかアレ
不通に数値(ID)の配列として保存するか...
んーでも、自分宛てのダイレクト投稿を一覧取得するケースもあるか...
renoteCount とか repliesCount とか reactionCounts とか保存すべき?
renoteCount (APIではnumber) 保存する
repliesCount (APIではnumber) 保存する
reactionCounts (APIではObject) 必ずNoteReactionsみたいなテーブルを見るとおもうので保存しない
とか?
ありがとうございます
必ずNoteReactionsみたいなテーブルを見るとおもう
んー、そんなことないかも
んー、そんなことないかも
JSON? 今みたいにNoteReactionを使うのかと…
あれ、今NoteReactioninsertしかしてない
typeormはやめてsequelize-typescriptにします
TypeORM 評判悪いと聞いていたので正直ほっとしました。
個々のIDが変わっても問題ないならばマイグレ用意することはできる
ただ大変という問題はあるけど
ユーザーに関しては、IDが比較可能である必要はない(ランダムな文字列で問題ない)ため、マイグレの際は以前のObjectIDをそのまま引き継ぐことが可能そう
現在のIDについては
https://docs.mongodb.com/manual/reference/method/ObjectId/
日付が含まれているものの、生成時期を考えると (上位4ビットが0になった時期がないので)
事実上固定長 (24文字hex文字列) なので比較可能だと思います。
また、現在のIDは上位の方のビットが0101までのIDが採番されているので
新たに1xxxなど最上位ビットが埋まっているIDなどを採番すれば重複することもないのではと思います。
そういえば: PostgreSQLになったらElasticSearchではなくなる?
sequelize-typescript は ActiveRecord しかできなくて微妙
PeerTube の開発者の方々にお伺いをたてるのも手かと。
Misskeyはデータベースから取得したレコードはすぐレスポンスとして返す場合がほとんど(いじくったりしない)ので、レコード自体にメソッドがあっても意味ないし、いちいちインスタンス化するコストもかかる
ORMによっては取得時にインスタンス化しないオプションを提供するものもあるけど、ほぼすべての find 時にそのオプションを true にするのは面倒すぎる
とりあえず sequelize の線は消えそう
PostgreSQLになったらElasticSearchではなくなる?
MastodonはPostgreSQLだけどElasticSearchを必要としていることからMisskeyでも引き続き必要になりそう
TypeORMに戻る
10%くらい終わった
v10時点でのデータベースの設計や命名などで気になっている点がある方は今のうちに言っておいてください
20%くらい終わった
ついでに #4018 もやる
型定義は作らないかもしれないけど、「不要な値を削除」方式ではなくこんな感じに「必要な値をコピー」する感じ
https://github.com/syuilo/misskey/blob/578143096f1accdc7e23a72b2cbe76768969d1f4/src/models/repositories/user.ts#L48-L84
型定義作るとしたら、せっかく作っても型定義とドキュメントが一致していないということが起こり得るので、ドキュメントから型定義を自動生成するようにする
それなら型定義とドキュメントが必ず一致することが保証される
今はAPIのパラメータの型情報はドキュメント(cafy定義)から自動生成している状態なのでそれと同じ感じで
modelのリファクタ系developとかv10なんたらとかのブランチにマージしておきたい気がします
↑今はmodel配下のマッピングの差分がわからなくなってしまったので
今まで models にあったものは models/entities と models/repositories に分割されました
entiriesにはスキーマ定義だけあって、repositoriesにはそのスキーマに属するメソッドが定義されます
例えば今までこのように書いていたものはこうなります
before
import Note, { INote, pack } from './models/note';
const foo: INote = bar();
const note = Note.findOne({ _id: x });
return pack(note);
after
import { Note } from './models/entities/note';
import { Notes } from './models';
const foo: Note = bar();
const note = Notes.findOne(x);
return Notes.pack(note);
entity と repository を区別するために、上の例にあるように repository の方は複数形になってます
Note が entity で Notes が NoteのRepostiry
entity は、上述のようにスキーマ定義であってメソッドなどは何も持ってないので、コード上で entity を使うのは型注釈のためだけになると思います
repository は実際にデータベースからデータを持ってきたり更新したりなどのいろいろなメソッドを持っているので頻繁に使います
30%くらい終わった
各種IDにULIDを使おうと思うんですけどどう思いますか?
IDが数値だと、例えばアクセスされたURLに含まれているIDを元にデータベースに問い合わせるようなシナリオで、プログラム上でいちいち文字列から数値に変換する必要があってめんどい
@syuilo
noteIdとかuserIdでもULIDにして、既存IDとの連続性とかは考慮しない感じでしょうか?
う~~~む
ランダムではないので連続性は保たれそう
ちゃんと元の順番通りinsertしていけば
ULIDほどのユニークさは求めてないのでULIDをちょっと改造したものになりそう
そもそもnoteIdとかuserIdって (同じIDで) 移行しますか?
Hex 24文字 => Base32 26文字 にするということは移行なしですかね?
IDは変わると考えてます
ID変えてしまうとユーザー移行が難しくなるのではと思います (AP的に)
こまこまのこまり
にすれば旧IDと重複しないので旧IDがそのまま使えて
順番も旧ID→新IDとつながると思います
So is there any plan to support other databases?
Database server is much cheaper than VPS. But not all ISPs provide MongoDB(or even PostgreSQL)... (MySQL and MS SQL Server are most widely used) If I were building my own site, I would like to just buy a database server instead of a VPS that I need to install MondoDB myself. 😄
Support is difficult because MySQL doesn't support arrays or JSON columns.
Most helpful comment
10%くらい終わった