15

MySQL で新しいデータ型を作成できませんでした。クエリを以下に示します

CREATE TYPE PERSON AS OBJECT
(NAME       VARCHAR (30),
 SSN        VARCHAR (9));

MySQLでそれを行うにはどうすればよいですか

4

3 に答える 3

23

それはいけません。MySQL にはユーザー定義型がありません。(少なくとも、現在のバージョンではありません。)

于 2012-04-22T07:38:26.153 に答える
4

JSON データ型を使用できるようになりました。MySQL は、バージョン 5.7 以降、ネイティブの JSON データ型をサポートしています。8.

于 2020-09-01T03:27:45.663 に答える
0

他の 2 つの答えは 100% 正しいです。どちらも、新しいスカラー タプル値を定義することはできず、JSON をネイティブ型として使用することで、ほとんどそこに到達できます。

3つの提案があります。まず、getter/setter でサポートされている特定の JSON スキーマを値に強制する方法の提案。2 番目に考えられる解決策は CTE によるものですが、それには書き込み側で追加の作業が必要であり、真のカスタム型の代わりにはなりません。3 番目のアプローチは、最初の 2 つの提案のハイブリッドのようなもので、サブクエリ ルックアップをカプセル化するゲッター/セッターを使用します。

さらに読む前に、以下はナプキンドラフト品質のスケッチを表しています. 何も期待しないでください。2020 年後半以降、MySQL を使用していません。

まず、コンストラクター/ゲッター/セッターのアプローチですが、これを実装するには多少の作業が必要になる可能性が高く、適切に設計されたインデックス作成でさえ、ルックアップのパフォーマンスでネイティブ列と競合することはできず、常により多くの時間がかかりますチャンク/ページ/ディスクのスペースですが、それは 90% の解決策です。C で構造体メソッドを実装する方法と同じように、それを行うと、名前空間の編成のためだけになり、ぎこちなくなります。

delimiter $$;
create function contact_encode(fname text, lname text, phone text, email text)
returns JSON
deterministic
begin
    /* validation stuff here? like maybe you care that they're not null
       and/or sane values for names and phone numbers and email addresses?
     */
    return json_object(
        'firstName', fname,
        'lastName', lname,
        'contactMethod', json_array(
            json_object(
                'type','phone',
                'value',phone
            ),
            json_object(
                'type','email',
                'value',email
            )
        )
    );
end$$
delimiter ;$$
/*  Yep, this approach probably actually sucks

    I was going to suggest something like contact_decode(JSON)->values...,
    but I forgot that you can't return multiple values from a function.
    That's the irony; it'd be easier to use JSON for custom types in
    languages that already support return tuples and custom types as relations. 

    Grrrrr
 */

うーん、うん。これはおそらく、MySQL を使用してカスタム型に到達できる最も近いものです。仮説では、次のようなゲッター/セッター関数のセットは、JSON 値/列の既存の MySQL 8 API を実際に改善すると考えられます。これも純粋に仮説ですが、あるレベルのカプセル化されたロジックを提供するエンコードされた動作を持つセッターの例です。

create function contact_get_name(contact JSON)
.....return concat(contact->>'firstName', ' ',contact->>'lastName')
.....
create function contact_set_name(contact JSON, value text)
....return json_replace(
        contact, 
        '$.firstName', substring_index(value, ' ', 1),
        '$.lastName'. substring_index(value, ' ', -1)
    )
.....

問題はたくさんあります。それが役に立てば、タイピングは MySQL 開発者としての私にとって深刻な制約ではありませんでした。現在、私は PostgreSQL をデフォルトとして使用する組織で働いていますが、カスタム型は素晴らしいものです (rowtype を返します、私はあなたを見ています)。 PostgreSQL より前の CTE で遊ぶことはできません。とはいえ、以下は MySQL に直接変換されない可能性があります。

「blog_user」というテーブルに列 (id、name、phone、email、username、password、blah-blah-blah .....) があるとします。テーブルのクエリでのテーブルの「カスタム タイプ」の使用呼び出された投稿 (id、author_id、タイトル、....) は次のようになります。

with author as (
    select
        id,
        substring_index(name, ' ', 1) as first_name,
        substring_index(name, ' ', -1) as last_name,
        email,
        concat('###-###-', right(phone, 4)) as phone
    from blog_user
) select
    concat(first_name, ' ', left(last_name, 1), '.') as name,
    title,
    yada-yada.....
from author, post
where author.id = post.author_id
and case 
    when @requested_blog_post is not null
        then post.id = @requested_blog_post
    when @title_search_term is not null
        then post.title like concat('%',@title_search_term,'%')
    else false
end

それは望ましい影響を達成し、部分結合として、実際にはかなり透過的でパフォーマンスが向上します...コアクエリのフィルターで使用されるCTEソース列に適切なインデックスがあると仮定します.

パフォーマンスに関しては、CTE を追加してサブクエリを作成し、特定の属性に部分的に結合する後者のアプローチは、JSON アプローチよりもはるかに優れていますが、JSON アプローチは間違いなく一部の人にとってより人間工学的です。いずれにせよ、MySQL で JSON を操作することに慣れています。

3 番目の解決策は、次のように、ID を受け取り、その ID の列の値を返すカスタム getter/setter 関数を定義することです。

create function post_get_author_name(requested_post int)
....
return (
    with author as (
        ....
    ) select 
        name 
    from author, post
    where author.id = post.author_id
    and post.id = requested_post
    limit 1 /*completely unnecessary in this case, but it's a thing I do anyway*/
)
....

このアプローチの難しさは、同じクエリで多数のゲッターを呼び出すことを示唆していることです。これは、ローカル CTE ソリューションよりも客観的にパフォーマンスが悪く、行ローカル JSON を使用した同じ getter/setter アプローチよりもパフォーマンスが悪い可能性があります。

要点は次のとおりです。申し訳ありませんが、カスタム型を使用することはできません。いくつかの近似値があり、数か月前にはあなたの痛みさえ理解できなかったでしょうが、お悔やみ申し上げます. おそらく実行可能な近似値をいくつか用意してください。

于 2021-08-04T14:38:26.670 に答える