データベース管理者

データベースのスキルを向上させ、コミュニティの他の人から学びたいデータベースの専門家向けのQ&A

3
IF EXISTSでクエリをラップすると非常に遅くなる
私は以下のクエリを持っています: select databasename from somedb.dbo.bigtable l where databasename ='someval' and source <>'kt' and not exists(select 1 from dbo.smalltable c where c.source=l.source) 上記のクエリは3秒で完了します。 上記のクエリが値を返す場合、ストアドプロシージャを終了する必要があるため、次のように書き直しました。 If Exists( select databasename from somedb.dbo.bigtable l where databasename ='someval' and source <>'kt' and not exists(select 1 from dbo.smalltable c where c.source=l.source) ) Begin Raiserror('Source missing',16,1) Return …

2
CREATE TABLE ASとSELECT INTO
PostgreSQLのサポートCREATE TABLE ASとSELECT INTOするとき、私は両方使うのですか? CREATE TABLE AS -クエリの結果から新しいテーブルを定義する CREATE TABLE ASテーブルを作成し、SELECTコマンドで計算されたデータでテーブルを埋めます。表の列には、の出力列に関連付けられた名前とデータ型SELECTがあります(ただし、新しい列名の明示的なリストを指定することで列名をオーバーライドできます)。 CREATE TABLE ASビューの作成と似ていますが、実際にはまったく異なります。新しいテーブルを作成し、クエリを一度だけ評価して、新しいテーブルに最初に入力します。新しいテーブルは、クエリのソーステーブルに対するその後の変更を追跡しません。対照的に、ビューSELECTは、クエリが実行されるたびに定義ステートメントを再評価します。 その後。 SELECT INTO -クエリの結果から新しいテーブルを定義する SELECT INTO新しいテーブルを作成し、クエリによって計算されたデータをそのテーブルに入力します。通常ののように、データはクライアントに返されませんSELECT。新しいテーブルの列には、の出力列に関連付けられた名前とデータ型がありSELECTます。
16 postgresql  ctas 

2
非整数の主キーに関する考慮事項
環境 分散アプリケーションからのデータを保存するデータベース(PostgreSQL 9.6)を設計しています。アプリケーションの分散された性質のSERIALため、潜在的な競合状態のため、自動インクリメント整数()を主キーとして使用することはできません。 自然な解決策は、UUID、またはグローバルに一意の識別子を使用することです。Postgresには組み込みのUUIDtypeが付属しており、これがぴったりです。 私がUUIDで抱えている問題は、デバッグに関連しています。それは人間に優しい文字列です。識別子ff53e96d-5fd7-4450-bc99-111b91875ec5は何も教えてくれませんが、ACC-f8kJd9xKCdが一意であるとは限りませんが、ACCオブジェクトを扱っていることを教えてくれます。 プログラミングの観点からは、いくつかの異なるオブジェクトに関連するアプリケーションクエリをデバッグするのが一般的です。プログラマーACCがORD(order)テーブルで(account)オブジェクトを誤って検索するとします。人間が読み取れる識別子を使用して、プログラマーは問題を即座に特定しますが、UUIDを使用して、何が問題なのかを理解するのに少し時間を費やします。 UUIDの「保証された」一意性は必要ありません。私はない、競合なしで鍵を生成するためのいくつかの部屋を必要とするが、UUIDは過剰です。また、最悪のシナリオでは、衝突が発生した場合、世界の終わりにはなりません(データベースがそれを拒否し、アプリケーションが回復できます)。したがって、トレードオフを考慮して、より小さくても人間に優しい識別子が私のユースケースにとって理想的なソリューションになるでしょう。 アプリケーションオブジェクトの特定 私が思いついた識別子の形式は次のとおりです。{domain}-{string}ここ{domain}で、はオブジェクトドメイン(アカウント、注文、製品)に置き換えられ{string}、ランダムに生成された文字列です。場合によっては{sub-domain}、ランダムな文字列の前にaを挿入することも理にかなっています。レッツは、の長さを無視{domain}し、{string}一意性を保証する目的のために。 インデックス作成/クエリのパフォーマンスに役立つ場合、形式のサイズを固定できます。 問題 知っています: のような形式の主キーが必要ですACC-f8kJd9xKCd。 これらの主キーは、いくつかのテーブルの一部になります。 これらすべてのキーは、6NFデータベースのいくつかの結合/関係で使用されます。 ほとんどのテーブルのサイズは、中規模から大規模(平均で最大100万行、最大で最大1億行)です。 パフォーマンスに関して、このキーを保存する最良の方法は何ですか? 以下に4つの解決策を示しますが、データベースに関する経験が少ないため、どれが最適かはわかりません。 考慮された解決策 1.文字列として保存(VARCHAR) (Postgresはの間に違いはありませんCHAR(n)とVARCHAR(n)、私は無視していますCHAR)。 いくつかの調査の後VARCHAR、特に結合操作での文字列比較は、を使用するよりも遅いことがわかりましたINTEGER。これは理にかなっていますが、この規模で心配する必要があるのでしょうか? 2.バイナリとして保存(bytea) Postgresとは異なり、MySQLにはネイティブUUIDタイプがありません。BINARY36 バイトのフィールドではなく、16バイトのフィールドを使用してUUIDを保存する方法を説明する投稿がいくつかありますVARCHAR。これらの投稿は、キーをバイナリとして保存するというアイデアを与えてくれました(byteaPostgresで)。 これによりサイズを節約できますが、パフォーマンスに関心があります。どの比較が高速であるかについての説明、つまりバイナリまたは文字列の説明を見つけることができなかった。バイナリ比較の方が速いと思います。もしそうであれば、プログラマは毎回データをエンコード/デコードする必要がありbyteaますがVARCHAR、おそらくの場合よりも優れています。 私は間違っているかもしれないが、私は両方だと思うbyteaとVARCHAR、バイト(または文字単位)による(平等)のバイトを比較します。この段階的な比較を「スキップ」し、単に「全体」を比較する方法はありますか?(私はそうは思いませんが、チェックの費用はかかりません)。 として保存するのbyteaが最善の解決策だと思いますが、私が無視している他の選択肢があるのではないかと思います。また、ソリューション1で述べたのと同じ懸念が当てはまります。比較のオーバーヘッドは心配するほど十分ですか? 「クリエイティブ」ソリューション 動作する2つの非常に「創造的な」ソリューションを思い付きました。どの程度であるかわかりません(つまり、テーブル内で数千行以上にスケーリングするのが難しい場合)。 3. UUID「ラベル」を付けて保存する UUIDを使用しない主な理由は、プログラマーがアプリケーションをよりよくデバッグできるようにするためです。しかし、両方を使用できる場合:データベースはすべてのキーをUUIDs としてのみ格納しますが、クエリが実行される前/後にオブジェクトをラップします。 たとえば、プログラマはを要求しACC-{UUID}、データベースはそのACC-部分を無視し、結果を取得して、すべてをとして返します{domain}-{UUID}。 おそらく、ストアドプロシージャまたは関数を使用したハッカーでこれが可能になるかもしれませんが、いくつかの質問が思い浮かびます。 これ(各クエリでドメインを削除/追加する)はかなりのオーバーヘッドですか? これも可能ですか? ストアドプロシージャや関数を使用したことがないため、これが可能かどうかもわかりません。誰かが光を当てることはできますか?プログラマと保存されたデータの間に透明なレイヤーを追加できれば、それは完璧なソリューションのようです。 4.(私のお気に入り)IPv6として保存 cidr はい、あなたはそれを正しく読みました。IPv6アドレス形式は私の問題を完全に解決することがわかりました。 最初の数オクテットでドメインとサブドメインを追加し、残りをランダム文字列として使用できます。 衝突確率は OKです。(ただし、2 ^ 128は使用しませんが、それでも大丈夫です。) 等値比較は(できれば)最適化されているため、単にを使用するよりもパフォーマンスが向上する可能性がありますbytea。 containsドメインとその階層がどのように表されるかに応じて、実際にいくつかの興味深い比較を実行できます。 たとえば0000、ドメイン「製品」を表すためにコードを使用するとします。キー0000:0db8:85a3:0000:0000:8a2e:0370:7334は製品を表します0db8:85a3:0000:0000:8a2e:0370:7334。 …

2
SQL ServerがPERSISTED列を定義と一致しないデータで埋めることは合法ですか?
計算列の奇妙な値に関するこの質問をフォローしていPERSISTEDます。そこでの答えは、この振る舞いがどのようになったかについていくつかの推測をします。 私は次を求めています:これは完全なバグではありませんか?されているPERSISTED列は、今までにこのように動作することが許可されていますか? DECLARE @test TABLE ( Col1 INT, Contains2 AS CASE WHEN 2 IN (Col1) THEN 1 ELSE 0 END PERSISTED) --depends on Col1 INSERT INTO @test (Col1) VALUES (ABS(CHECKSUM(NEWID()) % 5)), (ABS(CHECKSUM(NEWID()) % 5)), (ABS(CHECKSUM(NEWID()) % 5)), (ABS(CHECKSUM(NEWID()) % 5)), (ABS(CHECKSUM(NEWID()) % 5)) SELECT * FROM @test --shows impossible …

2
すべての子供の合計を見つける再帰的CTE
これは、再帰T-SQLクエリ(おそらくCTE)を使用して検索したいアセンブリツリーです。以下の結果が期待されます。任意の部品について、アセンブリごとの合計金額を知りたい。 つまり、「Rivet」を検索すると、直接の子の数だけでなく、アセンブリ内の各レベルの合計数を知りたいのです。 Assembly (id:1) | |-Rivet |-Rivet |-SubAssembly (id:2) | | | |-Rivet | |-Bolt | |-Bolt | |-SubSubAssembly (id:3) | | | |-Rivet | |-Rivet | |-SubAssembly (id:4) |-Rivet |-Bolt DESIRED Results ------- ID, Count 1 , 6 2 , 3 3 , 2 4 , 1 現在、直接の親を取得できますが、CTEを拡張してこの情報を上にロールアップできるようにする方法を知りたいです。 With …


1
複数の多対多の関係を持つビデオゲームビジネスドメイン用のデータベースの設計
私はデータベース設計が比較的新しいので、練習用に独自の仮想データベースを作成することにしました。ただし、多くの多対多(M:N)の関係があると考えているため、モデリングと正規化に問題があります。 一般的なシナリオの説明 このデータベースは、ゼルダシリーズで働いたさまざまな人々に関するデータを保持することを目的としています。私はのトラック維持したいコンソール(S)というゲームがで再生することができ、従業員に参加を持っていたゲーム開発をジョブズ従業員は、(多くの持っていた従業員が異なる上で働いていたジョブズ複数にわたるゲームなど、) ビジネスルール 複数の従業員が複数のゲームで作業できます。 同じコンソール上に複数のゲームを配置できます。 複数のコンソールを同じゲームのプラットフォームにすることができます。 複数の従業員が同じジョブを持つことができます。 アン従業員は複数持つことができますジョブを。 A ゲームは複数持つことができる従業員を。 ゲームは、複数の種類持つことができるジョブのそれの発展に 複数のゲームに同じタイプのジョブを添付できます。 A コンソールは複数持つことができます人々はそれに取り組んで。 A 人は複数で作業することができますコンソール。 属性名とサンプル値 FirstとLastに分割できる従業員名(「John」と「Doe」など) ゲームのタイトル(たとえば、「Ocarina of Time」) 役職(たとえば、「レベル設計」、「ディレクター」、「構成」、「レベル設計者」、「プログラマー」、「ローカリゼーション」など)。 コンソール名(「Game Boy Advance」など) 問題 これまでのところ、データの冗長性と、関心のあるエンティティタイプ間のM:N関係が至る所にあるように設計されているようです。しかし、データベース設計者は常にこの種の問題に遭遇しなければならないので、解決策が必要だと感じています。 注:テーブルを満たすデータを見つけることはできますが、問題は、正規化された形式のテーブルを持つデータベースにデータを整理することです。

4
データベースとしてのブロックチェーン(ビットコイン)?
私はこのBBCニュースの記事を読んでいて、次の抜粋が私の注目を集めました。Always On可用性グループまたは高可用性ミラーリングのように聞こえますが、セキュリティが自動的に含まれている場合があります。 ブロックチェーンは、トランザクション量の多い最新のアプリケーションにとって実行可能なデータベースソリューションですか? 個人の医療記録のような少量のトランザクションに価値があることは簡単にわかりますが、大量のデータベースについてはどうでしょうか? ブロックチェーンとは何ですか? ブロックチェーンは暗号化に依存しており、中央のアクターを必要とせずに一連のコンピューターがグローバルレコードを変更できるようにします。 仲介者を削除すると、ほぼすべての部門でコストが削減されます。 ブロックチェーンは、「ブロック」として知られるデータのコレクションに発生するすべてを時系列または「チェーン」で記録する台帳です。 通貨としてこれは重要な機能です。これにより、ユーザーは自分のデジタルマネーが種類の1つであることを確認できるため、ウォレット内の各紙幣が一意であるのと同じです。 「ブロックチェーン技術は、コピーせずにデジタル情報を転送できるため、私たちが資産を作成する方法になります」と、ブロックチェーンネットワークを構築するChain.comのCEO、Adam Ludwin氏は述べています。 ブロックチェーンは、あらゆる種類の情報の履歴を追跡し、その価値を維持するために使用できます。たとえば、医師はそれを使用して医療記録を更新できます。 ブロックチェーンへの各変更はネットワーク全体で同時に行われるため、情報が失われることはなく、変更を元に戻すことができないため、システムはその透明性を維持します。各ブロックを変更するには特別なキーが必要なので、個人はそのキーを保護することで記録を安全に保つことができます。

1
Postgresの0001年のタイムゾーンに、UTCからのこのようなクレイジーなオフセットがあるのはなぜですか?
Postgres 9.5では、年0001(ゼロ0000年なし)を試しているときに以下の結果が表示されたことに驚きました。 のオフセット-07:52:58? いくつかのサンプルコード。Iの混合使用することを注意TIMESTAMP WITH TIME ZONEしてTIMESTAMP WITHOUT TIME ZONE、慎重に読んでください。 SET TIME ZONE 'America/Los_Angeles' ; SELECT (TIMESTAMP WITH TIME ZONE '2015-01-01 00:00:00.0', TIMESTAMP WITH TIME ZONE '0001-01-01 00:00:00.0Z', TIMESTAMP WITHOUT TIME ZONE '0001-01-01 00:00:00.0Z') ; ("2015-01-01 00:00:00-08","0001-12-31 16:07:02-07:52:58 BC","0001-01-01 00:00:00") 私はその2番目の値に驚いています0001-12-31 16:07:02-07:52:58 BC。America/Los_AngelesUTCから8時間遅れているのと同じように、オフセットを8時間戻し-08:00ます。しかし-08:00、オフセットの代わりにです-07:52:58。どうして? UTCで問題なし UTCでデータを入力する場合、このような問題はありません。 SET TIME ZONE 'UTC' ; …

4
データベースへのバスルートの保存
いくつかの調査を行った結果、ルートを一連のストップとして保存する必要があることがわかりました。何かのようなもの: Start -> Stop A -> Stop B -> Stop C -> End 3つのテーブルを作成しました。 ルート 止まる ルートストップ ... RouteStopsはジャンクションテーブルです。 私のようなものがあります: ルート +---------+ | routeId | +---------+ | 1 | +---------+ | 2 | +---------+ 駅 +-----------+------+ | stationId | Name | +-----------+------+ | 1 | A | +-----------+------+ | 2 …

3
更新列がインデックスにない更新ステートメントに対するインデックスの影響
私はインデックスが遅くなると人々が言うのを常に見ますupdate、deleteそしてinsert。これは、まるで絶対的なものであるかのように、ブランケットステートメントとして使用されます。 データベースを調整してパフォーマンスを向上させている間、私はこの規則に論理的に矛盾していると思われるこのような状況に出くわします。 SQL Serverでは、他のほとんどのDBMSを使用すると考えられますが、インデックスは指定した特定の列に基づいて作成されます。挿入と削除は常に行全体に影響を与えるため、インデックスに影響を与えることはありませんが、更新はもう少しユニークに見えます。特定の列にのみ影響します。 インデックスに含まれていない列があり、それらを更新する場合、そのテーブル内の他の列にインデックスがあるために、それらは遅くなりますか? たとえば、私のUserテーブルには、1つまたは2つのインデックス、Identity / Auto Incrementカラムであるプライマリキー、および場合によっては外部キーカラム上の別のインデックスがあります。 電話番号や住所など、インデックスのない列を直接更新すると、どちらの状況でもこのテーブルのインデックスが他の列にあるため、この更新は遅くなりますか?更新している列はインデックスにないため、論理的には、インデックスを更新しないでください。どちらかと言えば、WHERE句でインデックスを使用すると、速度が向上すると思います。

3
データベース防災[終了]
閉じた。この質問はより集中する必要があります。現在、回答を受け付けていません。 この質問を改善したいですか?この投稿を編集するだけで1つの問題に焦点を当てるように質問を更新します。 4年前に閉鎖されました。 データベースが250GBを超えています。サードパーティのツールを使用して、スケジュールされたバックアップを作成します。 スケジュールデータベースバックアップは、SQL Serverデータベースを破損から保護する最良の方法ですか?または、他の何かをお勧めできますか?

3
SQL Serverがインデックスを無視するのはなぜですか?
CustPassMaster16列のテーブルがありCustNum varchar(8)、その1つがであり、indexを作成しましたIX_dbo_CustPassMaster_CustNum。SELECTステートメントを実行すると: SELECT * FROM dbo.CustPassMaster WHERE CustNum = '12345678' インデックスを完全に無視します。これは、CustDataMasterもう少し多くの列(55)を持つテーブルがあり、そのうちの1つが混乱しているためですCustNum varchar(8)。IX_dbo_CustDataMaster_CustNumこのテーブルのこの列()にインデックスを作成し、実質的に同じクエリを使用します。 SELECT * FROM dbo.CustDataMaster WHERE CustNum = '12345678' そして、作成したインデックスを使用します。 この背後に特定の理由はありますか?なぜインデックスを使用しますが、インデックスを使用しCustDataMasterませんCustPassMasterか?列数が少ないためですか? 最初のクエリは66行を返します。2番目の場合、1行が返されます。 また、追加のメモ:CustPassMaster4991レコードがあり、CustDataMaster5376レコードがあります。これがインデックスを無視する理由になりますか?CustPassMasterまた、同じCustNum値を持つ重複レコードもあります。これは別の要因ですか? この主張は、両方のクエリの実際の実行計画の結果に基づいています。 CustPassMaster(未使用のインデックスを持つもの)のDDLは次のとおりです。 CREATE TABLE dbo.CustPassMaster( [CustNum] [varchar](8) NOT NULL, [Username] [char](15) NOT NULL, [Password] [char](15) NOT NULL, /* more columns here */ [VBTerminator] [varchar](1) NOT NULL …

1
未使用のインデックスの削除-予期しない危険性の評価
7月にサーバーが最後に再起動されて以来蓄積されているDMV統計によると、数百の未使用のインデックスを持つ非常に大きなデータベースがあります。DBAの1人が次の警告文を作成しましたが、私には意味がありません。 インデックスを削除する前に、クエリオプティマイザーがこのインデックスの存在を必要とする可能性があるため、一意性制約が適用されていないことを確認する必要があります。 インデックスが作成されるたびに、そのインデックスに関連する統計もSQL Serverに作成されます。クエリはインデックスを使用していない可能性がありますが、統計を使用している可能性があります。そのため、インデックスを削除した後、特定のクエリパフォーマンスが非常に悪くなるという状況が発生する場合があります。SQL Serverは、統計の使用統計を保持しません。データベースで「統計の自動作成」機能を有効にしていますが、クエリオプティマイザーが不足している統計を作成する前に、すべてのパラメーターを内部で満たす必要があるかわかりません。 #1に関しては、SQL Serverは実際にインデックスのシークを行って、挿入/更新が行われる前に一意性を判断するため、インデックスは使用されていないようには見えません。 #2に関して、これは本当に可能ですか? ちなみに、インデックスを使用しないという場合、シークもスキャンもありません。
16 sql-server  index 

1
sysadmin以外のドメインユーザーが所有するSQL AgentジョブからSSISパッケージを実行する
大規模なSSIS展開の一部として、問題なく(SQL Serverエージェント経由で)夜間に実行される2つのSSISパッケージがあります。すべてがWindows認証を使用しており、スケジュールされたジョブはsysadmin(私も)によって所有され、SQL Serverエージェントサービスアカウントとして実行されます。 そのため、データは基本的にsource system ~> transit db ~> staging ~> NDS一晩で処理されます。 私はハンドル、気に2つのSSISパッケージtransit db ~> stagingとstaging ~> NDSデータの特定のセットのために、それぞれの部品。 ドメインユーザー(sysadmin以外)が何かを実行し、source system興味深いデータをにプッシュするtransit dbため、勤務時間中にこの更新されたデータをフェッチして更新する方法が必要NDSです。この人にとって最も簡単な方法は、そのETLは、マクロ対応のExcelブックのボタンをクリックすることで、ODBCを介してSQL Serverに接続し(Windows認証を使用)、ストアドプロシージャを実行します。 ストアドプロシージャは次のようになります。 create procedure dbo.UpdateMaterialInventory as begin execute msdb.dbo.UpdateMaterialInventory; end [msdb]の「姉妹」ストアドプロシージャは次のようになります。 create procedure dbo.UpdateMaterialInventory with execute as 'SqlAgentProxy' as begin execute msdb.dbo.sp_start_job N'NDS-ManualMaterialInventory'; end この[SqlAgentProxy]ユーザーは、ドメインユーザーのログインから[msdb]で作成したWindowsユーザーでexecute、このUpdateMaterialInventoryプロシージャへのアクセス許可を付与しました。これにより、ドメインユーザーににexecute許可を与える必要がなくなりますmsdb.dbo.sp_start_job。 SQL AgentジョブNDS-ManualMaterialInventoryはドメインユーザーが所有し、2つのステップがあり、それぞれ[SQL Server Integration …

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.