Believe you can

If you can dream it, you can do it.

ワイドモニターを導入して縦設置にしてみた

1年ぶりのPCネタ。

前回の記事はコチラ
chichi1091.hatenablog.jp

今回はワイドモニターを購入し、モニターアームも新調して縦2画面構成にしてみた。
購入したものは

japannext.net marantzpro.jp www.greenhouse-store.jp

色々調べているうちにJapanNextのモニターが勝手にウルトラワイドだと思い込んでいたようで、設置して接続してなんか違う。。ってなってしまった。
そうだよな。。この値段でウルトラワイド変えるわけないよなー。しかもUSBハブ機能もついているし。

※ウルトラワイドの解像度は29インチだと2560×1080みたいなので、これもウルトラワイドモニターのようでした。

でも購入の決め手になったのは値段の他にこのUSBハブ。
本業PCとプライベート兼副業自作PCのカメラやマイクが片方でしか使えなくていい方法ないかなーと思っていたところにモニター自体にハブがある機種があると知って購入を決めたので、これはサイコー。かんたんに切り替えができるのでこれから重宝しそう。

モニターアームは今まで横に並べていたモニターを見るのに結構首を動かす必要があってそのせいで肩こりとか起きてる気がしてので、縦設置に切り替えてみた。
これも成功で、首よりも机が広く使えるようになり、整理もしやすくなった。
上のモニターを見るのも動かす範囲が狭くなったので、これから期待。

今まで使っていたマイクがアームセットで2000円ぐらいだったためか、副業で声が聞こえないとかノイズがひどいとか色々言われていたため、購入を決めて適当に選んだ。
今の所苦情は来ていないので問題ないと思われるので、本業でも試していこうと思う。

完全なリモートワーカーになったので、自宅環境をアップグレードさせてきたけど次はネットワーク系になるのかな?
wi-fiを部屋に設置する感じかなー。嫁のチェックがあるので時間をおいてからかな。。

SpringBoot+JPAからTiDBを使ってみる

ZOZO Advent Calendar 2022 カレンダー Vol.3 の 15 日目の記事です。

前回はTiDBとMySQLの機能比較を行いました。

chichi1091.hatenablog.jp

今回はSpringBootとJPAを利用してTiDBに接続するための方法や注意点を整理していきたいと思います。

環境

以下の環境で動作確認を行いました。

  • Java 17
  • Kotlin 1.7.20
  • Spring Boot 3.0.0
  • Spring-Data-JPA
  • TiDB 6.1

TiDBをDockerで起動する

こちらを参照にさせていただきdocker-compose.yamlを作成しました。 v5.4.0を利用していますが、M1 Macで動かす場合はv6.1.0にする必要がありましたのでご注意ください。
それぞれのコンテナの役割は次の図が参考になると思います。

github.com

起動をしたらデータベースとユーザを作成していきます。さすがMySQL互換のTiDB、コマンドはMySQLのコマンドと同じ。なのでMySQLユーザであればおなじみのコマンドになります。

$ mysql -h 127.0.0.1 -P 4000 -u root

mysql> create database tidb_sample CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
Query OK, 0 rows affected (0.10 sec)

mysql> create user tidb@'%' IDENTIFIED by 'tidbpassword';
Query OK, 0 rows affected (0.02 sec)

mysql> GRANT ALL PRIVILEGES ON * . * TO tidb@'%';
Query OK, 0 rows affected (0.02 sec)

これでTiDBの準備は完了です。MySQL Workbenchなどで接続をしてみてください。

SpringBoot

TiDBはMySQL互換なので、HibernateMySQL dialectで接続することができるのですが、PingCAP社が作成したTiDB dialectを利用するとTiDB独自のWindow関数などの利用が行えるようになります。TiDB dialectが組み込まれたHibernateはまだspring-boot-starter-data-jpaに入っていませんので、6.0.0.Beta2以降のHibernate-Coreに差し替える必要があります。

サンプルが提供されているので簡単に行えると考えていましたが、SpringBoot3以外でHibernate-Coreの差し替えを行うと次の例外が起こりSpringBootが起動しません。。サンプルの通りTiDB dialectを利用するにはSpringBoot3を利用したほうがよさそうです。

java.lang.NoClassDefFoundError: javax/persistence/EntityManagerFactory
    at org.springframework.data.jpa.util.BeanDefinitionUtils.<clinit>(BeanDefinitionUtils.java:57) ~[spring-data-jpa-2.7.3.jar:2.7.3]
    at org.springframework.data.jpa.repository.support.EntityManagerBeanDefinitionRegistrarPostProcessor.postProcessBeanFactory(EntityManagerBeanDefinitionRegistrarPostProcessor.java:72) ~[spring-data-jpa-2.7.3.jar:2.7.3]
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:325) ~[spring-context-5.3.23.jar:5.3.23]
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:191) ~[spring-context-5.3.23.jar:5.3.23]
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:746) ~[spring-context-5.3.23.jar:5.3.23]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:564) ~[spring-context-5.3.23.jar:5.3.23]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) ~[spring-boot-2.7.4.jar:2.7.4]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734) ~[spring-boot-2.7.4.jar:2.7.4]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) ~[spring-boot-2.7.4.jar:2.7.4]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[spring-boot-2.7.4.jar:2.7.4]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) ~[spring-boot-2.7.4.jar:2.7.4]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) ~[spring-boot-2.7.4.jar:2.7.4]
    at com.example.TidbSpringbootJpaApplicationKt.main(TidbSpringbootJpaApplication.kt:14) ~[main/:na]

buid.gradleでは次のようにすることで差し替えることができます。

dependencies {
    implementation ("org.springframework.boot:spring-boot-starter-parent:3.0.0")
    implementation ("org.springframework.boot:spring-boot-starter-web:3.0.0")
    implementation ("org.springframework.boot:spring-boot-starter-data-jpa:3.0.0") {
        exclude group: "org.hibernate", module: "hibernate-core"
    }
    implementation ("org.hibernate.orm:hibernate-core:6.1.5.Final")
}

接続先(application.yml)

datasource にはDockerで定義した接続先を指定するだけで、MySQLのときと特に変わりはありません。JPAdatabase-platformHibernateの差し替えで利用できるようになったTiDB dialectを指定するぐらいで特段注意する点はないかと思います。

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:4000/tidb_sample
    username: tidb
    password: tidbpassword
    type: com.zaxxer.hikari.HikariDataSource
  jpa:
    database-platform: org.hibernate.dialect.TiDBDialect

JPA

テーブルは簡単なバグトラッキングシステムをイメージした以下の3テーブルを操作することにします。

  • Bugs:バグを管理するテーブル
  • Comments:バグのコメントを管理するテーブル
  • Accounts:アカウントを管理するテーブル

ざっくりとしたER図はこちら。

エンティティ

TiDBで auto_increment の利用ができないため自動採番を行いたい場合はシーケンスを利用する必要がありますので、 @GeneratedValue@SequenceGenerator でシーケンスの利用を指定しています。

@Entity
@Table(name = "bugs")
data class Bugs(
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator="bug_id")
    @SequenceGenerator(name="bug_id", sequenceName="bug_id_seq", allocationSize=1)
    @Column(name = "bug_id")
    val bugId: Int?,
    @Column(name = "date_reported")
    val dateReported: Date,
    @Column(name = "summary")
    val summary: String,
    @Column(name = "description")
    val description: String,
    @OneToOne
    @JoinColumn(name = "reportedBy", referencedColumnName = "account_id")
    val reportedBy: Accounts,
    @OneToOne
    @JoinColumn(name = "assignedTo", referencedColumnName = "account_id")
    val assignedTo: Accounts,
    @Enumerated(EnumType.STRING)
    val status: Status,
)

@Entity
@Table(name = "comments")
data class Comments(
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator="comment_id")
    @SequenceGenerator(name="comment_id", sequenceName="comment_id_seq", allocationSize=1)
    @Column(name = "comment_id")
    val commentId: Int?,
    @ManyToOne
    @JoinColumn(name = "bug_id", referencedColumnName = "bug_id")
    val bug: Bugs,
    @OneToOne
    @JoinColumn(name = "author", referencedColumnName = "account_id")
    val author: Accounts,
    val commentDate: Date,
    val comment: String,
)

@Entity
@Table(name = "accounts")
data class Accounts(
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator="account_id")
    @SequenceGenerator(name="account_id", sequenceName="account_id_seq", allocationSize=1)
    @Column(name = "account_id")
    val accountId: Int?,
    @Column(name = "name")
    val name: String,
    @Column(name = "email")
    val email: String,
)

これでHibernateddl-auto でテーブルを作成すると次のリソースが作成されました。

sequenceName で指定したテーブルが作られています。どうもTiDBではシーケンスはテーブルリソースとして作成され採番機能を実現しているようです。試しに account_id_seq にselectを行うと [42S02][1051] Unknown table '' とエラーが出てしまいます。 select nextval(account_id_seq); といったシーケンスを取得する関数を利用することで次の値を取得することができます。この辺はMariaDBに寄せてる感じです。

まとめ

使ってみた結果、MySQLに接続しているのとほぼ変わりなくTiDBを利用することができました。他のORマッパーでも利用することができると思いますが、TiDB dialectが吸収している差異を自力で解決する必要があるため、できるだけJPAを使うのがよさそうに思います(JPAに好き嫌いがあるとは思いますが)。
後は性能や運用面、費用で問題がなければ実運用でも十分採用することができるのではないかと感じました。2回に渡ってTiDBを調べてみましたが参考になれば幸いです。

TiDBとMySQLの機能比較

ZOZO Advent Calendar 2022 カレンダー Vol.3 の 9 日目の記事です。

久しぶりのブログ更新になります。前回からだいぶ時間が空いてしまったので定期的に書けるようにしていかないとと反省しています。。

NewDBと呼ばれる新しいデータベースが登場し利用事例が増えてきました。その中でもMySQL互換のTiDBについて耳にする機会が増えたので、MySQLとの機能比較を行ってみました。DB選定や移行検討の際にお役に立てれば幸いです。

TiDBとは

TiDBはPingCAP社が開発した分散型データベースで、RDBMSとNoSQLの機能を組み合わせたデータベースです。
MySQL互換のSQL解析機能を持っているためアプリケーションからはMySQLと同様のアクセスが可能であり、水平方向のスケーラビリティ・協力な一貫性・高可用性を兼ね備えています。

pingcap.co.jp

MySQLとTiDBの比較

アプリケーションから利用する際の機能比較になります。インフラ・運用面、費用などは利用する環境によってパターンが多く出てしまうため、対象外とします。

トランザクション分離レベル

(一つの表にまとめるのが困難だったので別途切り出してます...)

  • ダーティリード:コミットされていないデータを別トランザクションで読めてしまう
  • ノンリピータブルリード:コミットされたデータを別トランザクションが読めてしまう
  • ファントムリード:取得したデータに対して別トランザクションがInsert or Deleteしてコミットすると同じ条件で読み込むとデータが増減している

MySQL8

ダーティリード ノンリピータブルリード ファントムリード
READ UNCOMMITTED
READ COMMITTED
REPEATABLE READ
(デフォルト)
SERAIALAZABLE

TiDB

ダーティリード ノンリピータブルリード ファントムリード
READ UNCOMMITTED
READ COMMITTED
REPEATABLE READ
(デフォルト)
SERAIALAZABLE

その他

項目 MySQL8 TiDB 備考
DDL
  • 複数変更を伴うalter tableは使えない
権限
  • MySQL5.7に準拠
文字コードと順序
  • デフォルト文字コード:utf8mb4
  • デフォルト順序:utf8mb4_0900_ai_ci
  • MySQL5.7に準拠
  • ci:大小文字区別なし
  • cs:大小文字区別あり
  • _bin:バイナリ比較
索引
(index)
  • 実行プランあり
  • ヒント句の利用可能
一時テーブル
(temporary)
  • 利用可能
ビュー
(view)
  • 利用可能
分割
(partition)
  • 利用可能
自動採番
(auto increment)
  • 利用はできるが連番で採番されないので代わりにシーケンスを利用する
外部キー
(foreign key)
  • 定義できるが制約チェックやdelete cascadeは動作しない
ユニーク制約
(unique index)
  • 利用可能
検査制約
(check)
  • MySQL5.7に準拠
    • 制約はつけれるが動作しない

(data type)
  • SPATIALを除くMySQLの型が利用可能(ただし、JSON型は利用できるが実験的機)能
結合
(join)
  • 利用可能
    • サブクエリが遅いことがある
    • TiFlashやParallel Applyで改善するかも
トリガー
(trigger)
  • 利用不可
ストアドプロシージャ、関数
(procedure/function)
  • 利用不可
集計関数
(window function)
  • 利用可能
  • 一部利用可能(参考

まとめ

MySQL5.7をベースにしているだけあってMySQLと同等のことが行えそうです。ただ、

  • 外部キーの動作
  • auto increment

は、データの整合性・値を別途取得するなど、アプリでの対応が必要となり移行の際に改修ゼロとまではいかなそうです。外部キーはプロジェクトのルールで必須となっている場合もあるかと思うので、使えないのは厳しいかもしれませんね。 とは言いつつもここまで互換性があると、書き込み性能に困っているアプリケーションの移行先にTiDBが選ばれるのも分かる気がします。近い将来、機能差異もなくなるのではないかと思うと今後の動向を注目ですね。

次回はアプリケーション(SpringBoot+JPA)からTiDBを利用する記事を書こうと思います。

ながのJava、復活へ向けて 〜一緒に運営してくれる人募集〜

これといった活動もしていないのでご存知の方はいらっしゃらないと思いますが、2年ほど前に地方JUGとして「ながの Java」を立ち上げようとしていました。
過去の記事はこちら(開催記事は前職のテックブログとして公開)

chichi1091.hatenablog.jp

tech.contracts.co.jp

運も悪くコロナが始まってしまい勉強会どころではなくそのまま頓挫してしまう状況でした。
そして2年経過した先日、JJUG CCC 2022のアンカンファレンスで「地方JUG最近どうよ!?座談会」という話題があることを知りすぐに参加しました。

fortee.jp

座談会の中で僕のこのツイートを拾っていただきました。

それもあり、長野でJUGを立ち上げようとしたことを多くの方に知っていただき、応援や温かいお言葉を頂戴しました。改めてお礼させてもらいます。ありがとうございます!!

このチャンスを逃すわけにはいかない!ということで2年ぶりに「ながのJava」の立ち上げを目指したいと思います!!
ただ、まだどのように行っていくかは未計画です。このあたりも含め一緒に運営してくれる人をまた募集したいと思います。
(前回の反省点として一人運営は辛い厳しいというのを実感しております。。)

ご興味がある方は @chichi1091 に連絡いただけると幸いです。
ぜひぜひ地方JUGを一緒に盛り上げていきましょう!!

パーツを新調した自作PC

去年の夏休みに工作と謳って自作PCを作りました。
予算に限りもあり家にあったパーツを使いながら完成させた記事はこちら。

chichi1091.hatenablog.jp

時間をかけてゆっくりとパーツを集め、ようやく一区切りとなったので変化した自作PCスペックになります。

パーツ
Core i5 10400F BOX(6C/12T)
PRIME B460M-A (B460 1200 MicroATX)
M.2 SSD 1TB NEW
CMK32GX4M2A2666C16 (DDR4 PC4-21300 16GB 2枚組)
KRPW-L5-500W/80+ (500W)
CA-1J4-00S1WN-00 (Versa H18 MicroATX アクリル)
GIGABIT GTX1650 NEW
LED PCファン×3 NEW

グラボが新しくなったので軽めのゲームもできるようになりました(Ubuntuなので限られてしまいますが)
せっかくパワーアップさせたのでもっと活用してあげねば

LinuxでもWindowsコンテナ使いたいんじゃ

DockerでWindowsコンテナを使うためにはホストOSがWindowsである必要がある。
そもそもWindowsコンテナを必要とする人がWindowsを使っていることが珍しいと思うのですが、どうなんでしょう?

ということで、タイトルにある通りLinux上でもWindowsコンテナを使うことができないかと調べた結果、次のようなリポジトリを発見したので試していこうと思います。
コレ自体はMacOS上で利用することを想定していると思うのですが、LinuxUbuntu)でも行けるはず。。。

github.com

動作イメージとしては、VirtualBox上のWindowsにインストールされたDockerにホストOS(Linux)から接続を行い、Windows上で動いているWindowsコンテナにアクセスするそんな感じです。

環境

  • Ubuntu 22.04 LTS
  • VirtuallBox 6.1.34
  • Vagrant 2.2.19
  • Packer 1.6.1(必要に応じて)

Vagrant Boxのビルドを行い、VMを起動させる

※StefanSchererさんがVagrant Boxを用意してくれているので、実施しなくても問題ありません
※M1 Macでも動くWindowsが必要な場合は実施してもらえればです

Packerでビルドを行い、Windows Server 2019のVagrant Boxイメージを作成します。(Windows isoファイルが大きいので1時間以上かかります)

github.com

$ packer build --only=virtualbox-iso windows_2019_docker.json

しばらくするとVirtualBoxが起動してWindowsのインストールが始まると思います。DockerをインストールしたりWindowsUpdateを行ったりと色々行ってくれます。

windows_2019_docker_virtualbox.boxというファイルが作られます。

Vagrantを起動し、Docket contextでWindowsコンテナに切り替える

続いて次のリポジトリをCloneしてVagrant Boxを起動させます。

github.com

$ vagrant up --provider virtualbox 2019-box
Bringing machine '2019-box' up with 'virtualbox' provider...
==> 2019-box: Box 'StefanScherer/windows_2019_docker' could not be found. Attempting to find and install...
    2019-box: Box Provider: virtualbox
    2019-box: Box Version: >= 0
==> 2019-box: Loading metadata for box 'StefanScherer/windows_2019_docker'
    2019-box: URL: https://vagrantcloud.com/StefanScherer/windows_2019_docker
==> 2019-box: Adding box 'StefanScherer/windows_2019_docker' (v2021.05.15) for provider: virtualbox
    2019-box: Downloading: https://vagrantcloud.com/StefanScherer/boxes/windows_2019_docker/versions/2021.05.15/providers/virtualbox.box
==> 2019-box: Box download is resuming from prior download progress
==> 2019-box: Successfully added box 'StefanScherer/windows_2019_docker' (v2021.05.15) for 'virtualbox'!
==> 2019-box: Preparing master VM for linked clones...
    2019-box: This is a one time operation. Once the master VM is prepared,
    2019-box: it will be used as a base for linked clones, making the creation
    2019-box: of new VMs take milliseconds on a modern system.
==> 2019-box: Importing base box 'StefanScherer/windows_2019_docker'...
==> 2019-box: Cloning VM...
==> 2019-box: Matching MAC address for NAT networking...
==> 2019-box: Checking if box 'StefanScherer/windows_2019_docker' version '2021.05.15' is up to date...
==> 2019-box: Setting the name of the VM: windows-docker-machine_2019-box_1653714059442_57360
==> 2019-box: Clearing any previously set network interfaces...
==> 2019-box: Preparing network interfaces based on configuration...
    2019-box: Adapter 1: nat
    2019-box: Adapter 2: hostonly
==> 2019-box: Forwarding ports...
    2019-box: 3389 (guest) => 3389 (host) (adapter 1)
    2019-box: 5985 (guest) => 55985 (host) (adapter 1)
    2019-box: 5986 (guest) => 55986 (host) (adapter 1)
    2019-box: 22 (guest) => 2222 (host) (adapter 1)
==> 2019-box: Running 'pre-boot' VM customizations...
==> 2019-box: Booting VM...
==> 2019-box: Waiting for machine to boot. This may take a few minutes...
    2019-box: WinRM address: 127.0.0.1:55985
    2019-box: WinRM username: vagrant
    2019-box: WinRM execution_time_limit: PT2H
    2019-box: WinRM transport: negotiate
==> 2019-box: Machine booted and ready!
==> 2019-box: Checking for guest additions in VM...
==> 2019-box: Configuring and enabling network interfaces...
==> 2019-box: Mounting shared folders...
    2019-box: /home/chichi1091 => /home/chichi1091
==> 2019-box: Running provisioner: shell...
    2019-box: Running: scripts/create-machine.ps1 as C:\tmp\vagrant-shell.ps1

VirtualBoxを起動してみるとWindowsが起動していることがわかります。

$ docker context ls
NAME        DESCRIPTION                               DOCKER ENDPOINT               KUBERNETES ENDPOINT   ORCHESTRATOR
2019-box    2019-box windows-docker-machine           tcp://192.168.59.90:2376                            
default *   Current DOCKER_HOST based configuration   unix:///var/run/docker.sock                         swarm

Docker Engineにも追加されています。ではWindows上で動いているDockerに切り替えを行います。

$ docker context use 2019-box
2019-box
Current context is now "2019-box"

$ docker version
Client: Docker Engine - Community
 Version:           20.10.16
 API version:       1.41
 Go version:        go1.17.10
 Git commit:        aa7e414
 Built:             Thu May 12 09:17:30 2022
 OS/Arch:           linux/amd64
 Context:           2019-box
 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          20.10.6
  API version:      1.41 (minimum version 1.24)
  Go version:       go1.13.15
  Git commit:       8728dd2
  Built:            Fri Apr  9 22:45:40 2021
  OS/Arch:          windows/amd64
  Experimental:     false

OS/Archwindows/amd64になっています!これでLinux Dockerが Windows Docker Engineとつながっている状態です。
元の状態に戻す場合は以下のコマンドを実行してください。

$ docker context use default

Windowsコンテナへの接続

以下のコマンドを実行することで、VirtualBoxWindowsで起動しているWindowsコンテナに接続することができます。

$ docker run -it -v C:$(pwd):C:$(pwd) mcr.microsoft.com/windows/servercore:1809 powershell
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved. 

PS C:\> 

PowerShellが起動しました!しかもホストOSのディレクトリもちゃんとマウントされています。
VirtualBoxWindowsにいろいろなWindowsコンテナを入れておけばLinuxからも操作することができます。予想される利用方法はiisが多いのかな?開発はLinuxMacで行って動かすのはiisというのは意外とありそうな気がします。

M1 Macの場合はVirtualBoxが利用できないので変わりにParallelsを使えばイケそうな感じですね。
README.mdに書いてある内容をそのまま行ってみましたが、いろいろな可能性を秘めていて楽しそうです。

全文検索システムを作りたい〜構想編〜

こんにちは、GWが始まって10連休の方も多いのではないでしょうか。
転職したばかりとはいえ、有給が付与されているのでお休みも取れるのですがカレンダー通りです。

先週からWEB+DB PRESSやSoftware Designといった雑誌を紙で購入しているのですが、本棚にびっしり配置されていてだいぶ場所が取られてしまっています。自宅にある設備で自炊が可能なのではと思い、調べてみたらスキャンを1ページ1ページ自分で行えばPDFを作ることが可能とわかったので自炊を始めています。

ただただPDFを作るだけでもいいのですが、せっかくなら全文検索できるようにして必要な情報にアクセスしやすいようにしたいと考えています。
ということで、システム構築みに向けて色々検討してみます。

要件

全文検索が行えること

ほしい情報やキーワードで調べることができないとせっかく電子化した意味はないかなと考えています。なので、全文検索が行えることが必須条件となります。

WEBシステムであること

全文検索が入ることで必然的にWEBシステムというのも必須条件となっていきますかね。

コストはかけない

僕はお小遣い制です。結婚してからビタ一文もお小遣いが上がっていないのでできる限りコストは抑えることとします。

出先でも利用できること

出先でも利用できることを目標としたい。必須としないのは「コストをかけない」が難しくなるからです。費用対効果を見ながら検討していきます。

実現方法

自作でシステム構築

勉強も兼ねて自力でシステムを構築している方法。
ほしい機能や仕組みを実現できる反面、いつ出来上がるか全く予想できないので計画が頓挫してしまう恐れがある。

なんらかのOSSを利用する

全文検索OSSで提供しているものを利用する方法。
ほしい機能や仕組みがあるかは運次第になってしまうものの、すぐにでもサービスを立ち上げることが可能になる。

結論

悩むこともなく「なんらかのOSSを利用する」で進んでみようと思います。思い浮かぶのはFESSぐらいなので、他に何があるのか調査からしていくことにします。オススメのOSSがあればコメントください。