WebSurfer's Home

トップ > Blog 1   |   ログイン
APMLフィルター

MySQL 8.0 Command Line Client ツール

by WebSurfer 2023年10月5日 16:52

MySQL 8.0 のツールに Command Line Client と Command Line Client - Unicode がありますが、何が違うのかを調べてみました。調べたことを備忘録として書いておきます。

Command Line Client

ダウンロードサイト MySQL Community Downloads から MySQL 8.0 のインストーラーを入手し Windows PC にインストールすると、上の画像の赤枠で示すように MySQL 8.0 Command Line Client と MySQL 8.0 Command Line Client - Unicode という 2 つのツールが利用できるようになります。

何がどう違うのか調べていたら、MySQL のドキュメント「4.5.1.6 mysql Client Tips」の「Unicode Support on Windows」というセクションに説明が見つかりました。以下に記事の抜粋を載せておきます。

"Windows provides APIs based on UTF-16LE for reading from and writing to the console; the mysql client for Windows is able to use these APIs. The Windows installer creates an item in the MySQL menu named MySQL command line client - Unicode. This item invokes the mysql client with properties set to communicate through the console to the MySQL server using Unicode."

mysql client は Windows がコンソールを読み書きする UTF-16LE ベースの API を使うことができる。MySQL 8.0 Command Line Client - Unicode を起動することにより、mysql clien はコンソールを通じて MySQL server と Unicode を使って通信を行うようになる・・・ということらしいです。

具体的にどういうことになっているか、自分の環境(Windows 10 PC に MySQL 8.0.19 を Setup Type を Full に設定してインストール)で調べたことを以下に書きます。

まず、使われている charset (文字セット) をそれぞれの場合について調べました。結果は以下の画像の通りです。character-set-client, -connection, -results が異なるところに注目してください。character-set-database, -server は MySQL 8.0 のデフォルト utf8mb4 で両方同じとなっています。

Command Line Client

charset, Command Line Client

Command Line Client - Unicode

charset, Command Line Client - Unicode

character-set-client, -connection, -results の意味は MySQL のドキュメント「接続文字セットおよび照合順序」によると以下の通りです。

  • character_set_client: クライアントが送信するステートメントの文字セット
  • character_set_connection: サーバーがステートメントを受信したあと、変換する文字セット
  • character_set_results: サーバーがクライアントにクエリー結果を返信するときに使用する文字セット

上の画像の Command Line Client では character-set-client, -connection, -results が cp932 となっています。cp932 というのは Shift_JIS を Microsoft と OEM ベンダーが独自拡張した文字コードで、拡張部分を除けばほぼ Shift_JIS と思えばよさそうです。ということは Command Line Client で起動したコンソールからは Shift_JIS しか使えないということになるはずです。

例えば以下のようなテーブルが MySQL にあるとします。データベース、テーブルの charset は uft8mb4 です。このテーブルにツールで起動したコンソールからクエリを投げて試してみます。

MySQL のテーブル

ちなみに、上の画像の最後の行の Title 列の各文字は以下の通りです。

  • あ : Shift_JIS の文字
  • 丂 : Shift_JIS に無し、Unicode の BMP には含まれる
  • 𠀋 : サロゲートペア
  • 🍎 : サロゲートペア
  • 👨‍🌾 : サロゲートペア 👨 と 🌾 を ZeroWidthJoiner で連結

Command Line Client の場合は以下のようになります。Shift_JIS 以外は認識してくれないようです。

Command Line Client

Command Line Client - Unicode の場合は以下のようになります。𠀋 🍎 👨‍🌾 も where Title like '%〇%' の 〇 としては有効でした。

Command Line Client - Unicode

Tags: , ,

MySQL

PlanetScale を使ってみました

by WebSurfer 2023年2月15日 19:11

ASP.NET Core MVC アプリで PlanetScale をデーターベースに使ってみました。紆余曲折がありましたが何とか接続して使えるようになった結果が下の画像です。

PlanetScale を使ったアプリ

その紆余曲折と言うか、アプリの作成で自分が遭遇した問題は以下の通りです。

  1. EF Code First でテーブルを作成できない。
  2. 既存の DB からリバースエンジニアリングができない。
  3. BeginTransaction メソッドが使えない。

その顛末を以下に備忘録として書いておきます。上の各項目についても説明します。

PlanetScale とは何かですが、"PlanetScale is the world’s most advanced serverless MySQL platform" ということだそうで、要するに MySQL を使ったクラウド上のデータベースサーバーらしいです。制約として外部キー制約がつけられないということがあるそうです。

利用するにあたって、まず、PlanetScale にサインインしてデータベース名と地域を設定し、データベースを作成する必要があります。以下の画像がその設定の例です。

データベース名と地域を設定

データベースの作成に成功すると、以下のように自分が作成したデーターベース情報が表示されます。

自分の DB 情報

上の画像の[Connect]ボタンをクリックすると、下の画像のように接続情報が表示されます。Username と Password が表示されるのは初回のみなので必ず記録しておいてください

接続情報

さらに、上の画像の赤枠の[.NET]を選択すると ASP.NET Core アプリの appsettings.json に設定するための接続文字列の例が表示されますので、これも忘れないように記録しておくことをお勧めします。

以上はデータベース作成時からデフォルトで存在している main ブランチでの話です。このあと開発作業用にブランチを追加するのが普通ということなので自分もそうしてみました。気をつけなければならないのは追加した開発作業用ブランチへの接続用の Username と Password は main ブランチのものとは異なることです。

自分はそれを知らなくて半日ぐらいハマりました。開発作業用ブランチを作ってそれにテーブルを作成し、アプリからアクセスして SELECT クエリを投げたのですが、MySqlException がスローされてそのテーブルは見つからないと言われます。原因は Username と Password に main ブランチのものを使っていたので main ブランチに接続され、main ブランチにはそのテーブルは存在しないからでした。開発作業用ブランチに接続するには、開発作業用ブランチの Username と Password を使用する必要があるようです。

以上で PlanetScale 側のデータベースの準備は完了したはずなので、Visual Studio 2022 のテンプレートを使って .NET 6.0 の ASP.NET Core MVC のプロジェクトを新規に作成し、それから PlanetScale を使ってみます。

(1) EF Code First でテーブルを作成できない

最初に EF Code First の機能を使って PlanetScale にアプリが使うテーブルを作成してみます。先の記事「MySQL で Movie チュートリアル (CORE)」に書いた手順で、EF Code First の機能を利用して PlanetScale に Movie テーブルの作成をトライしてみました。

Add-Migration では問題なく Migration のためのクラスファイルが作成されます。しかし、Update-Database でのテーブルの作成に失敗します。

プロバイダに MySql.EntityFrameworkCore 6.0.10 を使った場合は、Update-Database の実行で KeyNotFoundException がスローされて失敗します。

Pomelo.EntityFrameworkCore.MySql 6.0.2 を使った場合は、ALTER DATABASE CHARACTER SET utf8mb4 というコマンドで失敗し "alter database is not supported" というエラーメッセージが出て、テーブルの作成に失敗します。

.NET 7.0 でも試してみましたが同じエラーで失敗します。

(2) リバースエンジニアリングができない

解決方法が分からないので、EF Code First による Movie テーブルの作成は諦めて、PlanetScale のサイトにアクセスして Console から手動で Movie テーブルを作成しました。下の画像の movie というのがそれです。

Console から手動で Movie テーブル作成

(注: __EFMigrationsHistory というテーブルもありますが、それは上に書いた EF Code First の操作でできたものです。その時は肝心の Movie テーブルは作成されていません)

先に作ったプロジェクトは放置して新たにゼロから ASP.NET Core MVC のプロジェクトを作成し、プロバイダには Pomelo.EntityFrameworkCore.MySql 6.0.2 を使って、リバースエンジニアリングでコンテキストクラスとエンティティクラスを作成をトライしました。

エラーなしで完了するもののコンテキストクラスしか生成されずその内容も不完全です。エンティティクラスは全く作成されません。

ちなみに、プロバイダに MySql.EntityFrameworkCore 6.0.10 を使った場合は KeyNotFoundException がスローされて何も生成されずに終わってしまいます。

これでは先に進めないので、不完全なコンテキストクラスは手直しして、エンティティクラスは自分でコードを書いて追加しました。その内容は以下の通りです。

コンテキストクラス

using Microsoft.EntityFrameworkCore;
using PlanetScaleMovie2.Models;

namespace PlanetScaleMovie2.Data
{
    public partial class myplanetscaleContext : DbContext
    {
        public myplanetscaleContext()
        {
        }

        public myplanetscaleContext(DbContextOptions<myplanetscaleContext> options)
            : base(options)
        {
        }

        // 以下の一行だけは自動生成されないので手動で追加
        public virtual DbSet<Movie> Movies { get; set; } = null!;

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            // 自動生成されたコードは不要なので削除
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.UseCollation("utf8mb4_0900_ai_ci")
                .HasCharSet("utf8mb4");

            OnModelCreatingPartial(modelBuilder);
        }

        partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
    }
}

エンティティクラス

using Microsoft.EntityFrameworkCore.Metadata.Internal;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;

namespace PlanetScaleMovie2.Models
{
    [Table("movie")]
    public partial class Movie
    {
        [Key]
        public int Id { get; set; }
        [Column(TypeName = "text")]
        public string? Title { get; set; }
        [Column(TypeName = "datetime")]
        public DateTime ReleaseDate { get; set; }
        [Column(TypeName = "text")]
        public string? Genre { get; set; }
        public decimal Price { get; set; }
    }
}

そのあとスキャフォールディング機能を使って Controller と View を作成します。

Controller と View の作成

Program.cs でコンテキストクラスを DI コンテナに登録します。

var serverVersion = new MySqlServerVersion(new Version(8, 0, 32));
var coonecctionString = builder.Configuration.GetConnectionString("PlanetScaleMovieContext");
builder.Services.AddDbContext<myplanetscaleContext>(options =>
    options.UseMySql(coonecctionString, serverVersion));

appsettings.json に上のコードの "PlanetScaleMovieContext" という名前で接続文字列を追加します。Movie テーブル を開発作業用ブランチに作った場合は、接続文字列の user と password は開発作業用ブランチ用のものにすることに注意してください。

以上でアプリは今度は問題なく動きました。その結果がこの記事の一番上の画像です。

(3) BeginTransaction メソッドが使えない

これはプロバイダに Oracle 製の MySql.EntityFrameworkCore を使った場合です。以下のように BeginTransaction メソッドの行で KeyNotFoundException がスローされます。

BeginTransaction メソッド

プロバイダに Pomelo.EntityFrameworkCore.MySql を使った場合は問題ありません。Oracle 製はどうも相性が良くないようです。

なお、上記 (1), (2) の件については planetscale / discussionDoes PlanetScale support the .NET 6/7 EF Code First and reverse engineering? という質問を出しました。解決に向けて進展がありましたらこの記事に追記します。

Tags: , , ,

CORE

.NET 6.0 ASP.NET Identity に MySQL 使用 (その2)

by WebSurfer 2023年2月12日 16:15

.NET 6.0 の ASP.NET MVC アプリで、プロバイダに Oracle 製 MySql.EntityFrameworkCore v6.0.10 を使って、ASP.NET Core Identity のユーザー情報のストアに MySQL を利用する話を書きます。

ASP.NET Identity に MySQL 使用

先の記事「.NET 6.0 ASP.NET Identity に MySQL 使用 (CORE)」では、その時点で Oracle 製 MySql.EntityFrameworkCore は v5.0.8 までしかリリースされていなかったので、プロバイダには Pomelo.EntityFrameworkCore.MySql を使用しています。

その後 Oracle 製 MySql.EntityFrameworkCore の .NET 6.0 用がリリースされたので試してみましたが、v6.0.7 までは Add-Migration に失敗して使えませんでした。

先日バージョンアップの状況を調べてみたら v6.0.10 がリリースされていたので試してみたら Add-Migration は成功するようになってました。その後 Update-Database でデータベースは生成され、Resister でのユーザー登録、Login でのユーザー認証も問題なくできます。(ただし、100% 完全に動くかどうかまでは未検証ですが)

と言うわけで、プロバイダに Oracle 製 MySql.EntityFrameworkCore v6.0.10 を使ってのアプリの作り方を、先の記事の Pomelo.EntityFrameworkCore.MySql と違う点だけ以下に書いておきます。

(1) NuGet パッケージ

NuGet で MySql.EntityFrameworkCore v6.0.10 をインストールします。他に必要なものとバージョンを合わせました。

MySql.EntityFrameworkCore

(2) Program.cs の修正

自動生成されれた Program.cs ファイルで、サービス登録のコードが SQL Server を使うように設定されているはずですが、これを MySQL を使うように変更します。以下のような感じです。

Program.cs の修正

(3) Add-Migration / Update-Database の実行

パッケージマネージャーコンソールから Add-Migration CreateIdentitySchema を実行します (CreateIdentitySchema という名前は任意です)。

xxxxx_CreateIdentitySchema.cs

Migrations と言う名前のフォルダとその中に xxxxx_CreateIdentitySchema.cs というファイル (xxxxx は作成時のタイムスタンプ) が生成されているはずですので確認してください。内容は Pomelo.EntityFrameworkCore.MySql を使った場合と若干異なります。

昔使った MySql.Data.EntityFrameworkCore(今は非推奨)で主キーの長さが指定されてなくて問題となったところは、Pomelo.EntityFrameworkCore.MySql と場合と同様に、varchar(255) に指定されています。

その後、Update-Database を実行すれば接続文字列で指定した名前で MySQL データベースが生成され、その中に ASP.NET Core Identity に必要なテーブルが一式生成されます。

MySQL データベース

Visual Studio から MVC アプリを起動し Register 画面からユーザー登録ができることを確認してください。登録したユーザーは上の MySQL データーベースに反映され、Login 画面から登録した ID とパスワードでログインできるようになります。

この記事の一番上の画像はログインした後で Manage 画面を開いたものです。

Tags: , , ,

CORE

About this blog

2010年5月にこのブログを立ち上げました。主に ASP.NET Web アプリ関係の記事です。

Calendar

<<  2024年3月  >>
252627282912
3456789
10111213141516
17181920212223
24252627282930
31123456

View posts in large calendar